[英]What does the :: operator do in this situation
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;
};
So I might have figured out that here the role of the '::' operator is to somehow feed/add into the 'value' variable the content of the operation performed earlier (N * Factorial). 所以我可能已经发现,这里'::'运算符的作用是以某种方式将先前执行的操作内容(N * Factorial)提供/添加到'value'变量中。 But can someone explain this in a more thorough manner (I wouldn't mind a full explanation of the '::' operator roles).
但有人可以更彻底地解释这一点(我不介意'::'运算符角色的完整解释)。
Thank you very much! 非常感谢你!
The ::
operator is called the scope resolution operator. ::
运算符称为范围解析运算符。 It "resolves," or makes clear, the scope in which the right-hand operand, a variable name, is located. 它“解析”或明确了右侧操作数(变量名称)所在的范围。
For example, std::cout
makes it clear to the compiler that the identifier cout
should be searched for in the namespace std
. 例如,
std::cout
使编译器清楚地知道应该在命名空间std
搜索标识符cout
。 In your case, the Factorial<N - 1>::value
makes it clear that value
is a member of the templated class Factorial<N - 1>
. 在您的情况下,
Factorial<N - 1>::value
表明value
是模板化阶段Factorial<N - 1>
。 It's used here because value
is a static
field of the class. 它在这里使用,因为
value
是类的static
字段。
So I might have figured out that
所以我可能已经弄清楚了
I strongly suggest learning C++ from a book, and learning to use existing reference material, rather than trying to figure out what some code means from first principles. 我强烈建议从一本书中学习 C ++,并学习使用现有的参考资料,而不是试图弄清楚一些代码从第一原理中意味着什么。 You're very likely to make subtle mistakes if you go by educated guesses.
如果你通过有根据的猜测,你很可能犯下微妙的错误。
The expression Factorial<N - 1>::value
is a qualified identifier . 表达式
Factorial<N - 1>::value
是限定标识符 。
Factorial<N - 1>
is the name of a class (an instantiation of the Factorial<int>
template with a specific value for the single parameter). Factorial<N - 1>
是一个类的名称( Factorial<int>
模板的实例化,具有单个参数的特定值)。 This class has a data member called value
. 该类有一个名为
value
的数据成员。 Explicit qualification is needed since this particular value
isn't otherwise in scope. 需要明确的鉴定,因为这个特定的
value
不在其他范围内。 See also qualified name lookup . 另请参见限定名称查找 。
You can use ::
like this for any class member: for example std::string::npos
roughly means find the data member called npos
in the class called string
in the namespace called std
. 您可以对任何类成员使用
::
like这样:例如std::string::npos
粗略意味着在名为std
的名称空间中名为string
的类中查找名为npos
的数据成员 。
... somehow feed/add into the 'value' variable the content of the operation performed earlier ...
...以某种方式提供/添加到'value'变量中之前执行的操作的内容......
there is no "earlier", this all happens during the same stage of compilation. 没有“早先”,这一切都发生在编译的同一阶段。
For example, I can manually write 例如,我可以手动编写
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; }
etc. etc. for as many values as I want. 等我想要的数量等等。 The templated version is effectively the same but saves a lot of typing.
模板化版本实际上是相同的,但节省了大量的输入。
Specifically, writing Factorial<3>
instantiates the template Factorial<int N>
for N=3
, which means we now have a concrete non-template class Factorial<3>
equivalent to the F_3
I wrote manually above. 具体来说,编写
Factorial<3>
实例化 N=3
的模板Factorial<int N>
,这意味着我们现在有一个具体的非模板类Factorial<3>
等同于我在上面手动编写的F_3
。
The definition of this class refers to Factorial<N-1>::value
(with N-1 = 2
), so Factorial<2>
gets instantiated too. 该类的定义是指
Factorial<N-1>::value
( N-1 = 2
),因此Factorial<2>
也会被实例化。 This chain of implicit instantiations continues until we reach the explicitly specialized Factorial<0>
(without that, it'd keep trying to instantiate Factorial<-1>
, Factorial<-2>
, forever until the compiler gave up and failed). 这个隐式实例化链继续,直到我们到达明确专门的
Factorial<0>
(没有它,它会一直试图实例化Factorial<-1>
, Factorial<-2>
,直到编译器放弃并失败)。
If you have a class foo
with a static member bar
, then you can refer to it with the ::
notation as foo::bar
. 如果你有一个带有静态成员
bar
的类foo
,那么你可以用::
notation作为foo::bar
来引用它 。
Here, Factorial<N - 1>
is a class, with a static member value
. 因此,
Factorial<N - 1>
是一个具有静态成员value
。 Asides from the template notation, there is no difference. 除了模板符号,没有区别。
struct Factorial
template class resolves value
from struct Factorial<N - 1>
and each time the value
is resolves recursively. struct Factorial
模板类从struct Factorial<N - 1>
解析value
,并且每次递归解析value
。 And at the end the value
will be 1
from the following base case : 最后,以下基本情况的
value
1
:
template <>
struct Factorial<0>
the value
determine here : value
确定在这里:
Factorial<5> f;
std::cout << f.value << std::endl;
So, the output will be : 120
因此,输出将是:
120
static const int value = N * Factorial<N - 1>::value
It means that the value of the member Factorial<N>::value
is N
multiplied by the value of the member Factorial<N-1>::value
. 这意味着成员
Factorial<N>::value
是N
乘以成员Factorial<N-1>::value
。 (Except for Factorial<0>::value
, which is specialised to provide a recursive base case ) (
Factorial<0>::value
除外,它专门用于提供递归基本情况 )
Both Factorial<N>
and Factorial<N-1>
are classes. Factorial<N>
和Factorial<N-1>
都是类。
::
is the scope resolution operator and tells the compiler that you want to access a member (in this case, a static
member) of the class (or namespace) to the left of it. ::
是作用域解析运算符,它告诉编译器您要访问其左侧的类(或命名空间)的成员(在本例中为static
成员)。
A simpler example: 一个更简单的例子:
class Foo
{
static int x;
};
int Foo::x = 42;
int main()
{
int y = Foo::x; // access the member 'x' in the class 'Foo'
}
or: 要么:
#include <iostream>
int main()
{
std::cout << "hi!\n"; // access the object 'cout' in the namespace 'std'
}
To make it more clear consider an alternative access to the data member value
. 为了更清楚地考虑对数据成员
value
的替代访问。
#include <iostream>
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;
};
int main()
{
std::cout << Factorial<12>().value << '\n';
}
The program output is 程序输出是
479001600
Here is used the member access expression Factorial<N - 1>().value
or Factorial<12>().value
. 这里使用了成员访问表达式
Factorial<N - 1>().value
或Factorial<12>().value
。
So to specify an access to the data member value
(and especially for non-static data members) you create an object of the type Factorial<N - 1>
or Factorial<12>. 因此,要指定对数据成员
value
的访问权限(尤其是对于非静态数据成员),请创建Factorial<N - 1>
或Factorial <12>类型的对象。
But static data members do not require an object of the class to be created. 但是静态数据成员不需要创建类的对象。 So it is much simpler and safer to use a class name and the operator :: to specify an access to a static data member.
因此,使用类名和operator ::指定对静态数据成员的访问权限要简单得多,也更安全。
The member access expression Factorial<N - 1>::value
specifies that value
is a static data member of the class Factorial<N - 1>
. 成员访问表达式
Factorial<N - 1>::value
指定该value
是Factorial<N - 1>
类的静态数据成员。 Neither object of the class Factorial<N - 1>
is required. Factorial<N - 1>
类的对象都不是必需的。 It is enough to specify the name of the class to which the static data member belongs. 只需指定静态数据成员所属的类的名称即可。
The '::-operator' is used to access things in namespaces (std::string) or static things in a class: ':: - operator'用于访问命名空间(std :: string)中的内容或类中的静态内容:
struct C {
static int i = 42;
};
int main() {
std::cout << C::i << '\n';
}
Here C::i is static, so I don't need an instance of class C. To access some non-static thing inside a class you use a '.'. 这里C :: i是静态的,所以我不需要类C的实例。要访问类中的一些非静态的东西,你使用'。'。 In your example Factorial is no class but a template, Factorial is a class and Factorial::value is the static int value inside the class Factorial.
在你的例子中,Factorial不是类而是模板,Factorial是一个类,Factorial :: value是Factorial类中的静态int值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.