元编程传递值的元编程应该是什么?

时间:2012-10-19 13:47:50

标签: c++ templates

我使用了

中的一个例子

http://en.wikipedia.org/wiki/Template_metaprogramming

const unsigned long long y = Factorial<0>::value; // == 1  

我理解编译器可以进行类型检查,但我认为你不能把0放在类型应该是的位置,它将作为值。

有人可以解释这是如何运作的吗?

由于

2 个答案:

答案 0 :(得分:4)

  

我认为你不能把0放在类型应该是的地方,它将被视为值

问题是假设:它不是“类型应该在哪里”。相反,它是“指定模板参数 的地方”。

在这种情况下,有一个非类型模板参数

它有效,因为它与类型模板参数不同。

就是这样。我可以在C++ Templates: the Complete Guide上推荐that list或许多其他书籍,以了解C ++模板的基础知识。

答案 1 :(得分:1)

在那个特定的例子中:

template <int N>
struct Factorial {
    enum { value = N * Factorial<N - 1>::value };
};

template <>
struct Factorial<0> {
    enum { value = 1 };
};

编译器以递归方式生成类。请记住,模板本身不是一个类,只是一组生成类的规则。

最初,只存在Factorial<0>。然后你写:

const int x = Factorial<4>::value;

告诉它需要生成类Factorial<4>,它将转换为:

template <>
struct Factorial<4> {
    enum { value = 4 * Factorial<3>::value };
};

再次告诉它生成类Factorial<3>,依此类推。当它到达Factorial<0>时会停止,因为它已经定义,并且不需要生成新类来计算其value成员。

基本上,它将计算从运行时移动到编译时。请注意,这并不总是有效(取决于N的值,您的编译器可能不支持那么多级别的模板递归)。此外,这增加了代码大小。

这是关于如何 - 这是因为它是标准所允许的。