2

我用了一个例子

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

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

我知道编译器可以进行类型检查,但我认为您不能将 0 放在类型应为的位置,并将其作为值。

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

谢谢

4

2 回答 2

4

我不认为你可以把 0 放在类型应该是的地方,它会被当作值

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

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

它之所以有效,仅仅是因为它是一个不同于type template arguments的特性。

就是这样。我可以推荐C++ Templates: the Complete Guide或该列表中的许多其他书籍来阅读 C++ 模板的基础知识。

于 2012-10-19T13:54:53.263 回答
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,您的编译器可能不支持那么多级别的模板递归)。此外,这会增加代码大小。

这是为了如何 - 为什么这样做是因为它是标准允许的。

于 2012-10-19T13:56:08.100 回答