Loki MakeTypelist递归模板让我感到困惑

时间:2020-11-04 04:10:24

标签: c++

我正在研究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 .....>吗?

1 个答案:

答案 0 :(得分:1)

由于定义了专业化template<> struct MakeTypelist<>,因此递归模板将终止,该专业化将返回NullType的{​​{1}}值。

这种专业化完全等同于代码的下一个变体

Result

因为如果没有提供全部或没有模板参数,那么所有未提供的模板参数都被认为等于默认值,即等于template<> struct MakeTypelist<NullType, NullType, NullType, NullType, ..... /* ... 18 Times ... */> // ....... (请参阅主模板定义,它具有所有18个具有默认值的参数类型= NullType

为那些未提供的模板参数选择默认参数的逻辑与使用带有默认参数的函数相同,例如如果您具有类似= NullType的功能,则可以用void f(int a = 0, int b = 0)f()f(0)三种不同的方式来调用它,所有这些都将给出相同的结果。而那些未提供的函数参数将被视为等于默认值。模板专业化方面也是如此-如果您不提供任何参数,即写f(0, 0),则所有18个参数类型都将被视为struct MakeTuplelist<>,因为所有18个参数均具有默认值NullType,类似于上面带有默认参数示例的函数中的行为。

此外,在专业化方面,您可能只提供一些模板参数,其余的将被视为等于默认值,例如= NullType专业化将与专业化template<> struct MakeTypelist<int, bool>完全相同。

然后递归终止,因为最后一条尾巴等于template<> struct MakeTypelist<int, bool, NullType, NullType, ...... /* 16 NullTypes */>,该末尾等于MakeTypelist<NullType, NullType, NullType, .....>的特殊版本,后者通过为MakeTypelist提供NullType的值来削减递归。

Try it online!

PS。相同的defaults-behavior不仅适用于模板的专业化,还适用于用法,在两种情况下,您都可以使用Resulttypedef MakeTypelist<> T;这样的模板,其余18种模板参数类型将等于默认值typedef MakeTypelist<int, bool> T;