从嵌套包中删除找到的第一个指定类型

钥匙

例如,

using NestedPack = Pack<long, char, double, Pack<long, int, short, int>, char, int>;

然后

RemoveFirstFoundFromNestedPack<int, NestedPack>::type

应该给

Pack<long, char, double, Pack<long, short, int>, char, int>

首先,我照顾了一个非嵌套包的情况:

template <typename T> struct Identity { using type = T; };

template <typename, typename, typename...> struct RemoveFirstFoundFromPackHelper;

template <typename RemoveMe, template<typename...> class P, typename... Types>
struct RemoveFirstFoundFromPackHelper<RemoveMe, P<>, Types...> {
    using type = P<Types...>;
};

template <typename RemoveMe, template<typename...> class P, typename First, typename... Rest, typename... Types>
struct RemoveFirstFoundFromPackHelper<RemoveMe, P<First, Rest...>, Types...> : 
    std::conditional<std::is_same<RemoveMe, First>::value,
        Identity <P<Types..., Rest...>>,
        RemoveFirstFoundFromPackHelper<RemoveMe, P<Rest...>, Types..., First>
    >::type {};

template <typename, typename> struct RemoveFirstFoundFromPack;

template <typename RemoveMe, template<typename...> class P, typename... Types>
struct RemoveFirstFoundFromPack<RemoveMe, P<Types...>> : RemoveFirstFoundFromPackHelper<RemoveMe, P<Types...>> {};

经过测试可以正常工作(使用std::is_same)。但是我对嵌套的情况感到困惑。这是我的最新尝试,给出了错误的结果(尽管我无法追查原因):

template <typename>
struct IsPack : std::false_type {};

template <template<typename...> class P, typename... Types>
struct IsPack<P<Types...>> : std::true_type {};

template <typename...> struct MergePacks;

template <typename Pack>
struct MergePacks<Pack> : Identity<Pack> {};

template <template <typename...> class P, typename... Types1, typename... Types2, typename... Packs>
struct MergePacks<P<Types1...>, P<Types2...>, Packs...> : MergePacks<P<Types1..., Types2...>, Packs...> {};

template <typename, typename, typename> struct RemoveFirstFoundFromNestedPackHelper;

template <typename RemoveMe, template<typename...> class P, typename... Types>
struct RemoveFirstFoundFromNestedPackHelper<RemoveMe, P<>, P<Types...>> {
    using type = P<Types...>;
};

template <typename RemoveMe, template<typename...> class P, typename First, typename... Rest, typename... Types>
struct RemoveFirstFoundFromNestedPackHelper<RemoveMe, P<First, Rest...>, P<Types...>> :
    std::conditional<std::is_same<RemoveMe, First>::value,
        Identity <P<Types..., Rest...>>,
        typename std::conditional<IsPack<First>::value,
            RemoveFirstFoundFromNestedPackHelper<RemoveMe, P<Rest...>, typename MergePacks<P<Types...>,
                typename RemoveFirstFoundFromPack<RemoveMe, First>::type>::type>,
            RemoveFirstFoundFromNestedPackHelper<RemoveMe, P<Rest...>, P<Types..., First>>
        >::type
    >::type {};

template <typename, typename> struct RemoveFirstFoundFromNestedPack;

template <typename RemoveMe, template<typename...> class P, typename... Types>
struct RemoveFirstFoundFromNestedPack<RemoveMe, P<Types...>> :
    RemoveFirstFoundFromNestedPackHelper<RemoveMe, P<Types...>, P<>> {};

我知道必须有比这更好的方法。

当然,一旦解决了这个问题,那么从嵌套包中删除所有指定类型的实例就应该是解决方案的一个简单变化(对于非嵌套情况,我已经做到了)。

TC

IsPack只要它没有非类型参数,您的特征就几乎可以匹配太阳下的每个模板,这是一个非常糟糕的主意。

template <class...> struct Pack {};

template <class, class, class = Pack<>> struct Remove_First;

// First one isn't a pack, and isn't what we are looking for.
template <class R, class F, class...Args1, class...Args2>
struct Remove_First<R, Pack<F, Args1...>, Pack<Args2...>> : Remove_First<R, Pack<Args1...>, Pack<Args2..., F>> {};

// First one is the type we are looking for.
template <class R, class...Args1, class...Args2>
struct Remove_First<R, Pack<R, Args1...>, Pack<Args2...>>  { using type = Pack<Args2..., Args1...>; };

// Didn't find the type
template <class R, class...Args>
struct Remove_First<R, Pack<>, Pack<Args...>>  { using type = Pack<Args...>; };

// Nested pack: Attempt to remove R from the nested pack
// Use is_same to check if a removal occurred and proceed accordingly
template <class R, class...Args1, class...Args2, class...ArgsNested>
struct Remove_First<R, Pack<Pack<ArgsNested...>, Args1...>, Pack<Args2...>> {
    using type = typename std::conditional<
                 std::is_same<typename Remove_First<R, Pack<ArgsNested...>>::type, Pack<ArgsNested...>>::value,
                 typename Remove_First<R, Pack<Args1...>, Pack<Args2..., Pack<ArgsNested...>>>::type,
                 Pack<Args2..., typename Remove_First<R, Pack<ArgsNested...>>::type, Args1...>>::type;
};

// if the type to remove is a Pack, and the first type in the list is a Pack,
// and they are the same pack, then remove it and we are done.
// if they are not the same Pack, then this specialization won't match,
// and we go into the recursion case as normal.
template <class...Args1, class...Args2, class...ArgsNested>
struct Remove_First<Pack<ArgsNested...>, Pack<Pack<ArgsNested...>, Args1...>, Pack<Args2...>> {
    using type = Pack<Args2..., Args1...>;
};

template<class R, class Pack>
using remove_first_t = typename Remove_First<R, Pack>::type;

前三个部分专业化处理从非嵌套包装中删除。嵌套包由第四部分专业化处理。它以递归方式对嵌套包执行删除操作。如果删除了一个类型(因此生成的类型与原始的嵌套包类型不同),那么我们就完成了。否则,我们将像往常一样继续处理外包装的其余部分。最终的专业化处理要删除的类型是其Pack自身的情况,否则,当存在该类型时,第二个和第四个部分专业化将匹配,并且两者都不比另一个专业化,从而导致歧义错误。

演示

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

从嵌套包中删除找到的第一个指定类型

来自分类Dev

从MySql中的指定列中删除第一个空格

来自分类Dev

建议xpath检查相同类型的嵌套元素中的第一个“文本”节点

来自分类Dev

Spark:从Scala的嵌套数组中删除第一个数组

来自分类Dev

Python:嵌套列表中的第一个元素

来自分类Dev

嵌套列表中的第一个值的总和

来自分类Dev

选择嵌套div中的第一个孩子

来自分类Dev

从文件中删除第一个多行注释

来自分类Dev

删除循环链表中的第一个元素

来自分类Dev

Typescript从函数中删除第一个参数

来自分类Dev

Lua从路径中删除第一个目录

来自分类Dev

sed +从路径中删除第一个目录

来自分类Dev

从sqldatareader对象的第一个中删除“〜/”

来自分类Dev

从链接列表中删除第一个

来自分类Dev

Java:删除拆分中的第一个单词

来自分类Dev

在列表中删除元组的第一个元素

来自分类Dev

从MKV文件中删除第一个音轨

来自分类Dev

删除数组中的第一个零

来自分类Dev

删除$ *中的第一个参数

来自分类Dev

如何从 NSString 中删除第一个空格?

来自分类Dev

从 <td> 中删除第一个单词

来自分类Dev

根据每个数组的第一个元素从嵌套数组中删除数组

来自分类Dev

遍历嵌套集合以找到与条件匹配的第一个子-子-子元素

来自分类Dev

Linux:从指定的搜索路径中找到第一个结果

来自分类Dev

不包含的定义,也找不到找到接受第一个类型参数的扩展方法

来自分类Dev

在CSS中,如何不选择第一个或最后一个类型?

来自分类Dev

从Haskell的列表中删除第一个和最后一个元素

来自分类Dev

删除行中第一个和最后一个元素的填充

来自分类Dev

如何删除列中的第一个单词和最后一个单词?

Related 相关文章

热门标签

归档