C++递归模板LargestTypeT工作原理及Rest类型展开疑问
C++ Typelist递归模板展开逻辑解析
我在阅读《C++ Templates - The complete guide》的Typelist章节时,遇到一段递归模板代码,对其展开逻辑存在疑惑:
using First = Front<List>;是获取Typelist的首类型,这点没问题;using Rest = typename LargestTypeT<PopFront<List>>::Type;是移除首类型后递归调用,但我原以为Rest会是Typelist<...>类型,可using Type = IfThenElse<(sizeof(First) >= sizeof(Rest)), First, Rest>;里是用单个类型和Rest比较大小,这说明Rest并不是Typelist,想知道它实际展开成什么类型?
核心模板代码
template<typename... Elements> class Typelist { }; template<typename List> class LargestTypeT; // recursive case: template<typename List> class LargestTypeT { private: using First = Front<List>; using Rest = typename LargestTypeT<PopFront<List>>::Type; // 原以为这里会展开成Typelist<...> public: using Type = IfThenElse<(sizeof(First) >= sizeof(Rest)), First, Rest>; }; // basis case: template<> class LargestTypeT<Typelist<>> { public: using Type = char; // 作为最小类型参与比较 }; template<typename List> using LargestType = typename LargestTypeT<List>::Type;
辅助工具模板(获取首类型与移除首类型)
template<typename List> class FrontT; template<typename Head, typename... Tail> class FrontT<Typelist<Head, Tail...>> { public: using Type = Head; }; template<typename List> using Front = typename FrontT<List>::Type; template<typename List> class PopFrontT; template<typename Head, typename... Tail> class PopFrontT<Typelist<Head, Tail...>> { public: using Type = Typelist<Tail...>; }; template<typename List> using PopFront = typename PopFrontT<List>::Type;
测试用例
给定Typelist:
Typelist<bool, int, long, short>
LargestType会返回列表中第一个出现的最大类型(此处为long)。
递归展开逻辑解析
你的疑惑点在于对Rest的类型理解错误——Rest并不是Typelist类型,而是递归调用LargestTypeT<PopFront<List>>后得到的单个最大类型。我们以Typelist<bool, int, long, short>为例,一步步拆解展开过程:
- 基础情况触发:当递归到空Typelist
Typelist<>时,LargestTypeT<Typelist<>>::Type是char(sizeof为1)。 - 递归倒数第一步:处理
Typelist<short>:First = short(sizeof为2)Rest = LargestTypeT<PopFront<Typelist<short>>>::Type = LargestTypeT<Typelist<>>::Type = char- 比较
sizeof(short) >= sizeof(char)(2>=1成立),所以Type = short
- 递归倒数第二步:处理
Typelist<long, short>:First = long(sizeof为8,假设64位环境)Rest = LargestTypeT<PopFront<Typelist<long, short>>>::Type = LargestTypeT<Typelist<short>>::Type = short- 比较
sizeof(long) >= sizeof(short)(8>=2成立),所以Type = long
- 递归倒数第三步:处理
Typelist<int, long, short>:First = int(sizeof为4)Rest = LargestTypeT<PopFront<Typelist<int, long, short>>>::Type = LargestTypeT<Typelist<long, short>>::Type = long- 比较
sizeof(int) >= sizeof(long)(4>=8不成立),所以Type = long
- 最外层调用:处理
Typelist<bool, int, long, short>:First = bool(sizeof为1)Rest = LargestTypeT<PopFront<Typelist<bool, int, long, short>>>::Type = LargestTypeT<Typelist<int, long, short>>::Type = long- 比较
sizeof(bool) >= sizeof(long)(1>=8不成立),所以Type = long
可见,每一层递归的Rest都是当前剩余Typelist中的最大单个类型,而非Typelist本身,因此sizeof(Rest)是合法的,能直接和First的sizeof做比较。
内容的提问来源于stack exchange,提问作者user11611653
相关产品推荐
相关产品推荐

