c++ - 模板别名难度

标签 c++ templates c++11 alias variadic

我有以下内容:

template <typename T, std::size_t End, std::size_t Count, template <typename...> class P,
typename... Accumulated, typename... Added, template <typename, T...> class Z, T... Is, 
std::size_t... Js>
struct Generate<T, End, Count, P<Accumulated...>, P<Added...>, Z<T, Is...>, Js...> :
    Generate<T, End, Count + 1, typename Merge<P, P<Accumulated...>,
        typename AppendEachToPack<T, P, Added, Is...>::type...>::type,
        typename Merge<P, typename AppendEachToPack<T, P, Added, Is...>::type...>::type,
        Z<T, Is...>, Js...> {};

因为 typename AppendEachToPack<T, P, Added, Is...>::type...被计算了两次,我想将上面的重写为

template <typename T, std::size_t End, std::size_t Count, template <typename...> class P,
typename... Accumulated, typename... Added, template <typename, T...> class Z, T... Is,
std::size_t... Js>
struct Generate<T, End, Count, P<Accumulated...>, P<Added...>, Z<T, Is...>, Js...> :
    GenerateAlias<T, End, Count + 1, P, P<Accumulated...>, Z<T, Is...>,
    typename AppendEachToPack<T, P, Added, Is...>::type..., Js...> {};

在哪里

template <typename T, std::size_t End, std::size_t Count, template <typename...> class P,
typename Output, typename Sequence, typename... Expanded, std::size_t... Js>
using GenerateAlias = Generate<T, End, Count, typename Merge<P, Output, Expanded...>::type,
typename Merge<P, Expanded...>::type, Sequence, Js...>;

但二包报关typename... Expanded, std::size_t... Js不被接受。那么我该如何实现我想要实现的目标呢?

如果您需要,这里是 AppendToEachPack 的定义和 Merge :

// Appending an element to a pack.
template <typename T, T t, typename> struct Append;

template <typename T, T t, template <T...> class Z, T... Is>  
struct Append<T, t, Z<Is...>> {  
    using type = Z<Is..., t>;
};

// Appending many elements to a pack one at a time.
template <typename T, template <typename...> class P, typename Pack, T... Is>
struct AppendEachToPack {
    using type = P<typename Append<T, Is, Pack>::type...>;
};

// Merging multiple packs of types into a single pack of types.
template <template <typename...> class P, typename... Packs> struct Merge;

template <template <typename...> class P, typename Pack>
struct Merge<P, Pack> {
    using type = Pack;
};

template <template <typename...> class P, typename... Ts, typename... Us>
struct Merge<P, P<Ts...>, P<Us...>> {
    using type = P<Ts..., Us...>;
};

template <template <typename...> class P, typename Pack1, typename Pack2, typename... Packs>
struct Merge<P, Pack1, Pack2, Packs...> {
    using type = typename Merge<P, Pack1, typename Merge<P, Pack2, Packs...>::type>::type;
};

最佳答案

感谢 T.C. 的提示,这是一种解决方案(经测试可正常工作):

// Helper struct to forward the pack wrapping the problem pack.
template <template <typename...> class P, typename PackOfPacks, typename... OtherPacks>
struct MergeMany;

template <template <typename...> class P, typename... Packs, typename... OtherPacks>
struct MergeMany<P, P<Packs...>, OtherPacks...> : Merge<P, Packs..., OtherPacks...> {};

// Now the desired GenerateAlias.
template <typename T, std::size_t End, std::size_t Count, template <typename...> class P,
    typename Output, typename Sequence, typename Expanded, std::size_t... Js>
using GenerateAlias = Generate<T, End, Count, typename MergeMany<P, Expanded, Output>::type,
    typename MergeMany<P, Expanded>::type, Sequence, Js...>;

// And now using GenerateAlias, so typename AppendEachToPack<T, P, Added, Is...>::type... is computed only once.
template <typename T, std::size_t End, std::size_t Count, template <typename...> class P, typename... Accumulated,
typename... Added, template <typename, T...> class Z, T... Is, std::size_t... Js>
struct Generate<T, End, Count, P<Accumulated...>, P<Added...>, Z<T, Is...>, Js...> :
    GenerateAlias<T, End, Count + 1, P, P<Accumulated...>, Z<T, Is...>,
    P<typename AppendEachToPack<T, P, Added, Is...>::type...>, Js...> {};

关于c++ - 模板别名难度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32511499/

相关文章:

c++ - Windows消息循环中的 sleep ()?

c++ - 奇怪的模板命名空间问题

c++ - 类模板 cpp、hpp、cpp

c++ - QT函数模板

C++ XML 解析器(速度,访问 DOM 树)

c++ - 这个 C++ 模板参数推导不正确吗?

c++ - Catch2:测试崩溃,因为封装在REQUIRE_THROWS中的调用引发异常

c++ - 如何正确地将 const_iterator& 传递给函数?

c++ - 使用 C++11 可变参数模板编写多维 "MathFunction"类

python - 如何使用 pybind11 包装模板类