tud*_*ion 3 c++ templates static-methods template-meta-programming
template <int N>
struct Factorial {
static const int value = N * Factorial<N - 1>::value;
};
// Base case via template specialization:
template <>
struct Factorial<0> {
static const int value = 1;
};
Run Code Online (Sandbox Code Playgroud)
因此,我可能已经发现,“ ::”运算符的作用是以某种方式将较早执行的操作的内容(N *阶乘)馈入/添加到“值”变量中。但是有人可以更彻底地解释这一点吗(我不介意对'::'运算符角色的完整解释)。
非常感谢你!
该::
运算符称为范围解析运算符。它“解析”或明确了右侧操作数(变量名)所在的范围。
例如,std::cout
使编译器清楚知道cout
应该在namespace中搜索标识符std
。在您的情况下,请Factorial<N - 1>::value
明确说明它value
是templated类的成员Factorial<N - 1>
。在这里使用它是因为value
是static
类的一个字段。
所以我可能已经发现
我强烈建议从书中学习 C ++,并学习使用现有的参考资料,而不是试图从基本原理中弄清楚某些代码的含义。如果您进行有根据的猜测,很可能会犯一些细微的错误。
该表达式Factorial<N - 1>::value
是一个合格的标识符。
Factorial<N - 1>
是类的名称(具有Factorial<int>
单个参数特定值的模板实例化)。此类具有名为的数据成员value
。需要明确的资格证明,因为此特殊 value
情况不在范围之内。另请参阅限定名称查找。
您可以::
对任何类成员使用这样的方法:例如,std::string::npos
粗略地表示在名为的命名空间中的类中找到被调用的数据成员npos
string
std
。
...以某种方式将先前执行的操作的内容馈入/添加到'value'变量中...
没有“较早的版本”,所有这些都发生在编译的同一阶段。
例如,我可以手动编写
struct F_0 { static const int value = 1; }
struct F_1 { static const int value = 1 * F_0::value; }
struct F_2 { static const int value = 2 * F_1::value; }
struct F_3 { static const int value = 3 * F_2::value; }
Run Code Online (Sandbox Code Playgroud)
等等等等,以获得我想要的尽可能多的值。模板化版本实际上是相同的,但是节省了大量输入。
具体而言,写作Factorial<3>
实例化模板Factorial<int N>
的N=3
,这意味着我们现在有一个具体的非模板类Factorial<3>
相当于F_3
我写上面的手动。
此类的定义引用Factorial<N-1>::value
(带有N-1 = 2
),因此也Factorial<2>
被实例化。隐式实例化链将一直持续到我们达到显式专用化为止Factorial<0>
(否则,它将一直尝试实例化Factorial<-1>
,,Factorial<-2>
直到编译器放弃并失败为止)。