我使用了
中的一个例子http://en.wikipedia.org/wiki/Template_metaprogramming
const unsigned long long y = Factorial<0>::value; // == 1
我理解编译器可以进行类型检查,但我认为你不能把0放在类型应该是的位置,它将作为值。
有人可以解释这是如何运作的吗?
由于
答案 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
的值,您的编译器可能不支持那么多级别的模板递归)。此外,这增加了代码大小。
这是关于如何 - 这是因为它是标准所允许的。