C++模板可变参数std::size_t序列反转失效问题排查
问题分析与修正
你的问题出在递归逻辑的设计上:你当前的代码只是把序列的第一个元素循环移到末尾,而且因为初始Count值等于元素个数,执行了和元素数量相同的移动次数,导致序列绕回了原顺序,自然看不到反转效果。
为什么原代码无效?
我们一步步拆解你的RecursiveClass<5u, 10u, 1u, 6u, 478u, 23u>实例化过程:
- 初始:
RecursiveClass<5,10,1,6,478,23>→ 继承RecursiveClass<4,1,6,478,23,10>(把10移到末尾) - 第二次递归:
RecursiveClass<4,1,6,478,23,10>→ 继承RecursiveClass<3,6,478,23,10,1>(把1移到末尾) - 重复这个过程直到第5次递归后,
Count减到0,此时序列回到了10,1,6,478,23,和原序列完全一致!
这就是为什么输出没有变化——你相当于把序列循环移动了一圈,又回到起点了。
修正方案:实现真正的序列反转
要实现可变参数序列的反转,我们需要调整递归逻辑:每次递归处理剩余序列,把当前第一个元素追加到已反转序列的末尾。这里提供两种贴近你原始思路的实现方式:
方式1:基于辅助模板的反转(兼容C++11)
我们给NonRecursiveClass添加一个模板别名用于追加元素,再通过递归逐步构建反转序列:
#include <iostream> using namespace std; // 保留你的打印函数 template<typename = void> void print(void) { std::cout << std::endl; } template<typename... T> void print(std::size_t index, T... indexes) { std::cout << index << ' '; print(indexes...); } // 修改NonRecursiveClass,添加追加元素的模板别名 template<std::size_t... Indexes> class NonRecursiveClass { public: void show(void) { print(Indexes...); } // 用于在当前序列末尾添加新元素的模板别名 template<std::size_t New> using append = NonRecursiveClass<Indexes..., New>; }; // 递归反转模板 template<std::size_t... Ts> struct ReverseSequence; // 终止条件:空序列 template<> struct ReverseSequence<> { using type = NonRecursiveClass<>; }; // 递归逻辑:反转[First, Rest...] = 反转(Rest...) 追加 First template<std::size_t First, std::size_t... Rest> struct ReverseSequence<First, Rest...> { using type = typename ReverseSequence<Rest...>::type::template append<First>; }; int main(void) { // 使用反转后的类型 ReverseSequence<10u, 1u, 6u, 478u, 23u>::type foo; foo.show(); // 输出:23 478 6 1 10 return 0; }
方式2:简化递归继承(更贴近你的原始写法)
如果你想继续用继承链的方式实现,可以调整递归模板的参数结构,直接构建反转序列:
#include <iostream> using namespace std; // 保留打印函数 template<typename = void> void print(void) { std::cout << std::endl; } template<typename... T> void print(std::size_t index, T... indexes) { std::cout << index << ' '; print(indexes...); } template<std::size_t... Indexes> class NonRecursiveClass { public: void show(void) { print(Indexes...); } // 用于在当前序列末尾添加新元素的模板别名 template<std::size_t New> using append = NonRecursiveClass<Indexes..., New>; }; // 递归反转类 template<std::size_t... ToReverse> class RecursiveReverse; // 终止条件:单个元素,直接继承NonRecursiveClass template<std::size_t Last> class RecursiveReverse<Last> : public NonRecursiveClass<Last> {}; // 递归逻辑:反转[First, Rest...] = 反转(Rest...) 追加 First template<std::size_t First, std::size_t... Rest> class RecursiveReverse<First, Rest...> : public RecursiveReverse<Rest...>::template append<First> {}; int main(void) { RecursiveReverse<10u,1u,6u,478u,23u> foo; foo.show(); // 输出:23 478 6 1 10 return 0; }
内容的提问来源于stack exchange,提问作者Pippin
相关产品推荐
相关产品推荐

