这是模板实例化工作原理的简化版本(我将通过Boost 文档了解 fold)。
假设您是一个 C++ 编译器(我们称您clang
为……这是一个很酷的名字),并且您很高兴地读入一个.cpp
文件以编译它。您会看到所有这些正常功能void foo()
,例如float magic(int x, double p)
和int main(int argc, char** argv)
。然后,你会遇到这样的事情:
template <typename T>
struct is_fun
{
typedef some_other_type<T> something_else;
typedef typename something_else::value value;
}
在这里,clang
说:酷,我知道这个名为 的结构is_fun
,它是一个以单一类型作为参数的模板。此时,is_fun
是一个未初始化的模板。重要的是要注意它在这里没有编译任何东西。当clang
看到模板化的任何东西时,它会检查语法(在它能够做到的程度)并继续前进。没有办法在目标代码中发出未初始化的模板 - 它是纯 C++ 且未编译的。
后来,它出现并看到is_fun
在这样的语句中使用:
typedef vector<long,float,short,double,float,long,long double> types;
typedef fold<
types,
int_<0>,
if_< is_fun<_2>,next<_1>,_1 >
>
::type number_of_fun;
现在,clang
他很懒,只是说“好吧,number_of_fun
只是那个可怕的东西的别名。” 再一次,它什么也没做。稍后在您的代码中,它会看到:
int foo()
{
const int fun = number_of_fun::value;
return fun;
}
现在number_of_fun
,它对模板做了一些事情。现在,模板参数将被填充值(因为 usingnumber_of_fun::value
需要它)。 clang
将逐步完成所有 Boost 内容,并最终以您的模板化is_fun
. 它需要的列表中的第一件事是 a long
(这就是折叠向量所做的),因此它创建了一个基于 long 的新类型,并T
填充了所有 s:
struct is_fun<long>
{
typedef some_other_type<long> something_else;
static const int value = typename something_else::value;
}
这种类型将被编译,因为它已被使用。C++模板的基本规则是:当你在编译过程中使用它时,它会被实例化,这意味着它会被编译。在运行时没有什么特别需要做的。