Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板别名困难_C++_Templates_C++11_Alias_Variadic - Fatal编程技术网

C++ 模板别名困难

C++ 模板别名困难,c++,templates,c++11,alias,variadic,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,

我有以下资料:

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...> {};

多亏T.C.的提示,这里有一个解决方案(经测试工作正常):

//用于转发包装问题包的包的Helper结构。
模板
结构合并多;
模板
结构MergeMany:Merge{};
//现在,理想的一代人出现了。
模板
使用GenerateAlias=Generate;
//现在使用GenerateAlias,所以typename AppendEachToPack::type。。。只计算一次。
模板
结构生成:
生成性{};

仅使用alias模板是不可能的。如果需要传递多个包,则需要一个支架,然后使用部分专用化或函数模板+
decltype
提取。我认为这种关于“
typename AppendEachToPack::type…
被计算两次”的担心在任何情况下都是错误的,这是由于记忆。
Generate
到底应该做什么?例如,
Create
将生成一个
a
Pack
,其中前2个组件将是0、1或2,接下来3个组件将是0或1。我已经完全解决了它,但我只想完成一些优化。也许
Expanded…
Js…
可以用两个包来包装,这样编译器就可以接受语法了?让我看看我是否理解正确:从您的示例中得到的包有3*3*2*2*2=72个成员,每个成员的形式都是
A
,其中
x
y
来自{0,1,2}而
z
w
u
几乎都是从{0,1}开始的。但这不是问题所在。我已经解决了。我只是想学习如何避免重复计算。如果你愿意,我可以在一个链接中发布我的完整解决方案,这样你就可以看到最初的目标是什么。这是链接,您可以运行它并查看输出:嗯,为什么输出中有
0
之类的内容?至于“重复计算”,编译器会记住它已经实例化的模板专门化,所以这通常不是问题。
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...>;
// 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;
};
// 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...> {};