在模板元程序中,typedef究竟是如何工作的?

时间:2014-08-17 01:49:48

标签: c++ templates typedef template-meta-programming

我是模板元编程的新手。在研究它时,我遇到了这个小代码块,它在编译时决定了类型。我的问题是,这个typedef如何在这里工作。程序执行的顺序究竟是什么?

#include <iostream>

using namespace std;

template <bool condition, class Then, class Else>
struct IF
{
    typedef Then RET;
};

template <class Then, class Else>
struct IF<false, Then, Else>
{
    typedef Else RET;
};


int main()
{
    // if sizeof(int) < sizeof(long) then use long else use int
    IF< sizeof(int)<sizeof(long), long, int >::RET  i;

    cout << i << endl;

    return 0;
}

2 个答案:

答案 0 :(得分:0)

这些typedef正在为模板参数类型ThenElse创建别名。

编译期间的表达式IF<sizeof(int)<sizeof(long), long, int >::RET i;按以下方式计算。

  1. 名称查找,将名称标识符IFstruct IF匹配。
  2. 扣除template struct IF的模板参数。
  3. 模板特化是一等公民,因此编译器首先检查扣除的模板参数是否与template struct IF的任何特化相匹配。如果sizeof(int) < sizeof(long)评估为false,则专业化template <class Then, class Else> struct IF<false, Then, Else>匹配,因此template struct IF的特化实例化,IF::RET评估/别名为int,因为template struct IF RET的特殊化别名为第二个模板参数(即Else)。如果sizeof(int) < sizeof(long)评估为true,则专业化不匹配,并且原始template class IF已实例化。在前一种情况下,IF::RET评估/别名long,因为在原始模板中RET别名为第一个模板参数(即Then)。

答案 1 :(得分:0)

Typedef只是其他类型的别名。不知何故,模板需要一种将类型转发给用户的方式,因此它根据条件的真实性在每个特化中创建一个公共typedef成员。

这是您的主要模板:

template<bool condition, class Then, class Else>
struct IF;

IF将始终采用三个参数。第一个是非类型模板布尔参数,以及将被&#34;返回的两种类型(ThenElse)&#34;通过模板取决于condition的真实性。

以下内容称为专业化:

template <class Then, class Else>
struct IF<false, Then, Else>;

更具体地说,这被称为部分专门化,因为您没有专门化每个模板参数。如果您是模板参数列表(template<...>中括号之间的内容)将为空。这就是所谓的显式专业化。


无论如何,当您实例化模板时,它会尝试根据给定的参数选择最佳的专业化。如果一个模板比另一个模板更专业,则选择该模板。您的主要模板充当&#34;默认&#34;模板,如果部分专业化的模板不可行(意味着condition不是true),则它会回退到主模板,即所选择的模板。因此,在这种情况下,它充当错误条件的模板。您甚至可以在部分特化中基于false而不是true进行专门化,在这种情况下,模板的角色会被切换。

由于我的平台上sizeof(int)<sizeof(long)为真,因此IF会以下列方式实例化:

IF<true, long, int>

这与部分特化完全匹配,因此选择了一个。

在部分特化中,有一个名为RET的公共成员类型定义,它将提供的第二个类型参数别名化。同样,第一个模板别名为第一个类型参数。

通过模板访问

RET,其别名的类型为int。那么您的代码相当于i被声明为int

int i;

如果condition为false,则主模板将被实例化,RET将为long,这将使i的类型{{1}同样。