文章目录
传送门 ==>> AutoSAR实战系列300讲「糖果Autosar」总目录
1 C++ 中的模板元编程
预测以下 C++ 程序的输出。
#include <iostream>
using namespace std;
template<int n> struct funStruct
{
enum { val = 2*funStruct<n-1>::val };
};
template<> struct funStruct<0>
{
enum { val = 1 };
};
int main()
{
cout << funStruct<8>::val << endl;
return 0;
}
输出:
256
程序计算“2 的 8 次幂(或 2^8)”。事实上,结构体funStruct可用于计算任何已知 n(或常数 n)的 2^n。上述程序的特殊之处在于:计算是在编译时完成的。因此,计算 2^8 是编译器完成的。要了解编译器是如何做到这一点的,让我们考虑以下关于模板和枚举的事实:
- 我们可以将非类型参数(不是数据类型的参数)传递给类/函数模板。
- 与其他 const 表达式一样,枚举常量的值是在编译时计算的。
- 当编译器看到模板的新参数时,编译器会创建模板的新实例。
让我们仔细看看原始程序。当编译器看到funStruct<8>::val,它尝试创建一个参数为 8 的funStruct实例,结果证明funStruct<7>还必须创建,因为枚举常量val必须在编译时进行评估。对于funStruct<7>,编译器需要funStruct<6>等等。最后,编译器使用funStruct<1>::val并且编译时递归终止。因此,使用模板,我们可以编写在编译时进行计算的程序,这样的程序称为模板元程序。模板元编程实际上是图灵完备的,这意味着任何可由计算机程序表达的计算都可以以某种形式由模板元程序计算。模板元编程通常不用于实际程序,但它是一个有趣的概念。