std::make_inedex_sequence的作用是产生一个0,1,2,3,….,N-1的序列。并由index_sequence<0,1,..N-1>来接受结果.从网上的资料看到了两种写法,在此基础上添加了自己的理解。
头插法:
//接受产生的序列
template<size_t... Args>
struct index_sequence{};
 //用于产生序列的递归写法  
template<size_t N, size_t... M>
struct make_index_sequence : public make_index_sequence<N-1, N-1, M...>
{
 
};
/*
如果N写为5的话就是如下的展开

make_index_sequence<5, NULL>
make_index_sequence<4,4, NULL> 
4,NULL被当成下一个M
make_index_sequence<3, 3, 4,NULL> 
3, 4,NULL被当成下一个M
make_index_sequence<2, 2, 3, 4,NULL> 
2, 3, 4,NULL被当成下一个M
make_index_sequence<1, 1, 2, 3, 4,NULL> 
1, 2, 3, 4,NULL被当成下一个M
//触发了结束条件,不再递归
make_index_sequence<0, 0, 1, 2, 3, 4,NULL> 
*/
 
 //定义结束条件
template<size_t... M>
struct make_index_sequence<0, M...>: public index_sequence<M...>
{
 
};

 

尾插法

//接受产生的序列
template<size_t ... Args>
struct index_sequence{};

 //好像没用上
template<typename T, size_t newValue>
struct AppendNewValue;
 
 //可以理解为一个函数
template<size_t... Args, size_t newValue>
struct AppendNewValue<index_sequence<Args...>, newValue>{
    using type = index_sequence<Args..., newValue>;
}
 
// 递归核心
template<size_t N>
struct make_index_sequence
{
    using type = typename AppendNewValue<typename make_index_sequence<N-1>::type, N-1>::type;
}
  
// 结束条件
template<>
struct make_index_sequence<0>
{
    using type = index_sequence<>;
}

/*
尾插法从数学归纳法的角度来看为好
当N=0时, 对应到特化模板make_index_sequence<0>,生成的序列是空的,即{}
当N=1时,N=0的基础上等价于调用了函数AppendNewValue 添加了数字0, {0}
 make_index_sequence<0> 
 -> typename make_index_sequence<N-1>::type = {} 
 -> 调用AppendNewValue添加0
 -> {}.append(0)
 -> {0}
 当N=2时,在N=1的基础上,上面已经推出是{0},就额外添加数字1,结果为{0,1}
 由此可推导N为任意数的整个序列的生成
*/

 

参考:

C++14 make_index_sequence的实现原理(简单明了)

 

 

最后修改日期: 2025年3月2日

作者