c++ - Loki MakeTypelist 递归模板让我很困惑
问题描述
我正在研究 loki 源代码。下面是MakeTypelist
让我感到困惑的。
class NullType {};
template <class T, class U>
struct Typelist
{
typedef T Head;
typedef U Tail;
};
template
<
typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
>
struct MakeTypelist
{
private:
typedef typename MakeTypelist
<
T2 , T3 , T4 ,
T5 , T6 , T7 ,
T8 , T9 , T10,
T11, T12, T13,
T14, T15, T16,
T17, T18
>
::Result TailResult;
public:
typedef Typelist<T1, TailResult> Result;
};
template<>
struct MakeTypelist<>
{
typedef NullType Result;
};
using MyType=MakeTypeList<int, unsigned int, long, unsigned long, float>
递归模板如何终止?
它无法匹配空类型版本MakeTypelist
,到底它会匹配MakeTypelist<NullType, NullType, NullType, NullType .....>
吗?
解决方案
template<> struct MakeTypelist<>
由于定义了返回NullType
值的特化,递归模板将终止Result
。
这种特化完全等同于代码的下一个变体
template<>
struct MakeTypelist<NullType, NullType, NullType, NullType, ..... /* ... 18 Times ... */>
// .......
因为如果没有提供所有或没有提供模板参数,那么所有未提供的模板参数都被认为等于默认值,即 to = NullType
(参见主模板定义,它具有所有 18 个参数类型具有 default = NullType
)。
为那些未提供的模板参数选择默认参数与使用具有默认参数的函数具有相同的逻辑,例如,如果你有类似的函数,void f(int a = 0, int b = 0)
那么你可以用三种不同的方式调用它f()
,f(0)
并且f(0, 0)
所有的都会给出相同的结果。那些未提供的函数参数将被视为等于默认值。在模板专业化中也是如此 - 如果您不提供任何参数,即 writestruct MakeTuplelist<>
那么所有 18 个参数类型将被认为是NullType
因为所有 18 个参数都有 defaults = NullType
,与上面带有默认参数示例的函数中的行为相同。
同样在专业化中,您可以只提供一些模板参数,其余的将被视为等于默认值,例如,template<> struct MakeTypelist<int, bool>
专业化将与专业化完全相同template<> struct MakeTypelist<int, bool, NullType, NullType, ...... /* 16 NullTypes */>
。
并且递归终止,因为最后一个尾等于MakeTypelist<NullType, NullType, NullType, .....>
which 匹配的专用版本MakeTypelist
通过为 提供NullType
值来减少递归Result
。
PS。相同的 defaults-behavior 不仅适用于模板的特化,还适用于用法,您可以使用类似模板,typedef MakeTypelist<> T;
或者typedef MakeTypelist<int, bool> T;
在这两种情况下,其余 18 个模板参数类型将等于 defaults = NullType
。
推荐阅读
- php - laravel 中的未知格式化程序“句子”错误
- react-native - 使用 testID 自动化移动应用程序是好是坏?
- aws-lambda - 与常规 lambda 函数结合时,Cloudfront 事件函数的大小太大
- javascript - 单选按钮值第二次没有改变
- python - Conda 可以安装任何(甚至更旧)版本的 Python 吗?
- algorithm - 贪心算法能保证找到解决方案吗?
- python - 如何在 x 轴上绘制所有值
- python-newspaper - Newspaper3k 抓取几个网站
- apache-spark - 为什么 Spark 查询在第二次执行时运行得更快?
- json - Series 类型的对象不是 JSON 可序列化的