我用模板实现了整数列表:
template<int ... Int>
struct IntList;
template<int H, int ... T>
struct IntList<H, T...>{
static const int Head = H;
using Tail = IntList<T...>;
};
template<>
struct IntList<>{};
我想定义元函数来处理 IntList
: IntCons
允许将列表增加一个元素,并且 Generate
这允许生成一个长度为 N 的列表,其中的整数是从 0 到 N-1 的整数(用法示例: using L = Generate<5>::type; // IntList<0,1,2,3,4>)
。
我定义 IntCons
这样:
template<int H, typename IL>
struct IntCons;
template<int H, int... Tail>
struct IntCons<H, IntList<Tail...>>{
using type = IntList<H, Tail...>;
};
而且我无法定义元函数 Generate
以这样的方式使用函数 IntCons
里面。
这是提示,根据我需要在 Generate
中使用默认参数.
template<int N /*, typename IL = default parameter?*/ >
struct Generate;
template<int N /*, typename IL = default parameter?*/ >
struct Generate<N>{
using type = ......;
};
元函数Generate有哪些定义方式,如何实现?
最佳答案
你的 Generate
与 std::make_index_sequence
非常相似;也许你可以搜索一个实现。
只是为了好玩,我提出以下线性方法(简单但效率不高)
#include <type_traits>
template <int ...>
struct IntList
{ };
template <int N, int ... Next>
struct Generate : public Generate<N-1, N-1, Next...>
{ };
template <int ... Next>
struct Generate<0, Next ... >
{ using type = IntList<Next ... >; };
int main()
{
static_assert( std::is_same<Generate<5>::type,
IntList<0, 1, 2, 3, 4>>{}, "!" );
}
更好的方法(但不是那么简单)可以是下面的(对数)
template <int...>
struct IntList
{ };
template <typename, typename>
struct ConcatLists;
template <int ... S1, int ... S2>
struct ConcatLists<IntList<S1...>, IntList<S2...>>
{ using type = IntList<S1..., (sizeof...(S1)+S2)...>; };
template <int N>
struct Generate
{ using type = typename ConcatLists<
typename Generate<(N>>1)>::type,
typename Generate<N-(N>>1)>::type>::type; };
template<>
struct Generate<0>
{ using type = IntList<>; };
template<>
struct Generate<1>
{ using type = IntList<0>; };
int main()
{
static_assert( std::is_same<Generate<5>::type,
IntList<0, 1, 2, 3, 4>>{}, "!" );
}
-- 编辑 --
OP 询问
thank you. Please, can you explain how first example works? I don't understand how works this line:
template <int N, int ... Next> struct Generate : public Generate<N-1, N-1, Next...> { };
我认为理解它的最好方法是遵循来自 Generate<5>
的链, 带到 Inlist<0, 1, 2, 3, 4>
.
Generate<5>
(5
与0
不同,因此只有Generate
的主版本适用)从N
继承(5
是Next...
;Generate<4, 4>
为空) .
Generate<4, 4>
( 4
不同于 0
)从 N
继承( 5
是 Next...
; 4
是 Generate<3, 3, 4>
) .
现在应该清楚了。
Generate<3, 3, 4>
继承自 Generate<2, 2, 3, 4>
.
Generate<2, 2, 3, 4>
继承自 Generate<1, 1, 2, 3, 4>
.
Generate<1, 1, 2, 3, 4>
继承自 Generate<0, 0, 1, 2, 3, 4>
.
现在N
为零。所以 Generate
的两个版本匹配,但偏特化 ( struct Generate<0, Next ... >
) 更特化并且是使用过的,并且 ( Next...
是 0, 1, 2, 3, 4
) 我们有
struct Generate<0, 0, 1, 2, 3, 4>
{ using type = IntList<0, 1, 2, 3, 4>; };
结论:Generate<5>
继承自 Generate<0, 0, 1, 2, 3, 4>
包含 type
定义为 IntList<0, 1, 2, 3, 4>
.
关于c++ - 使用模板元编程 [C++11] 对整数列表进行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47561679/