[英]Scope resolution operator and const
Let's take the following code: 让我们看下面的代码:
#include <string> // std::string
using namespace std;
int main() {
//const::int i = 42; -> Error: "expected id-expression before 'int'"
const::string str = "Foo"; // No error: why?
}
Why does this code compiles? 为什么要编译此代码? The error "expected id-expression before XXX" is only present when XXX is a fundamental type.
仅当XXX是基本类型时,才会出现错误“ XXX之前的预期id表达式”。
const::char c = 1; // error: expected id-expression before 'char'
const::double d = 2; // error: expected id-expression before 'double'
const::float f = 3; // error: expected id-expression before 'float'
const::bool b = 4; // error: expected id-expression before 'bool'
const::string
is parsed as const ::string
. const::string
被解析为const ::string
。 ::string
means to look up string
in the global namespace, and since you have injected std
into the global namespace, std::string
is found and everything is dandy. ::string
表示在全局名称空间中查找string
,并且由于您已将std
注入全局名称空间,因此找到了std::string
,并且所有操作都变得很花哨。
int
is a built-in type and isn't in any namespace, so there's no such thing as ::int
or std::int
, hence the error. int
是内置类型,不在任何名称空间中,因此不存在::int
或std::int
的错误。
::something
tells the compiler to look for something
in global namespace, but int
is keyword (not defined anywhere), while string
(resp. std::string
) is class defined in <string>
so your code is equivalent to this one ::something
告诉编译器去寻找something
在全局命名空间,但int
是关键字(不说明什么),而string
(相应std::string
)是定义的类<string>
这样的代码就相当于这一个
#include <string> // std::string
using namespace std;
int main() {
//const ::int i = 42; -> Error: "expected id-expression before 'int'"
const ::string str = "Foo";
}
It compiles because 它之所以编译是因为
using namespace std;
pulls the entire std
namespace into the global namespace, so ::string
is the same as std::string
. 将整个
std
名称空间放入全局名称空间,因此::string
与std::string
相同。 Your line in question is actually interpreted as 您所讨论的行实际上被解释为
const ::string str = "Foo";
However, int
is a keyword (and a fundamental type), and not a user-defined name that resides in any namespace. 但是,
int
是关键字(和基本类型),而不是驻留在任何名称空间中的用户定义名称。 So ::int
doesn't make sense. 所以
::int
没有意义。
Your using namespace std;
您正在
using namespace std;
is bit of a red herring. 有点红鲱鱼。 Note that
const::std::string str = "Foo";
注意
const::std::string str = "Foo";
also compiles. 也可以编译。 The reason this compiles (and the reason your
const::string str = "Foo";
compiles) is because ::
is the scope resolution operator. 之所以进行编译(以及您的
const::string str = "Foo";
编译的原因)是因为::
是作用域解析运算符。 Spacing is irrelevant. 间距无关紧要。 Just as there's no difference between
a+b+c
and a + b + c
, there's no difference between const::string str
and const :: string str
(and similarly, between const::std::string str
and const :: std :: string str
). 就像
a+b+c
和a + b + c
之间没有区别一样, const::string str
和const :: string str
之间也没有区别(同样, const::std::string str
和const :: std :: string str
之间也没有区别) const :: std :: string str
)。
::
, ::std::
, and std::
are all examples of a nested-name-specifier , which is described in 5.1.1 ¶8 of c++ n3290 (a draft of the C++11 standard). ::
, ::std::
和std::
都是嵌套名称说明符的所有示例,在c ++ n3290(C ++ 11标准的草案)的5.1.1¶8中进行了描述。 The const
is a keyword and this cannot be interpreted as the leading part of a nested-name-specifier . const
是一个关键字,不能将其解释为nested-name-specifier的开头 。 This means that const::string
can only be interpreted as if you had written const ::string
. 这意味着
const::string
只能像您已经写过const ::string
一样被解释。
In the context of using namespace std;
在
using namespace std;
的上下文中using namespace std;
at global namespace level, there's nothing wrong with using ::string
because the leading ::
means to look up what follows in the global namespace. 在全局名称空间级别,使用
::string
没什么问题,因为前导::
表示查找全局名称空间中的内容。 You've pulled all of namespace std
into the global namespace. 您已将所有名称空间
std
放入全局名称空间。 Thus const::string str
declares str
as a const
-qualified variable of type std::string
. 因此
const::string str
声明了str
作为const
-qualified类型的可变std::string
。
What about const::int i = 42;
那么
const::int i = 42;
? ? There's no place in the standard for such a construct.
在这种构造的标准中没有地方。 Looking at 7.1.6.2 ¶1 (c++n3290), A simple-type-specifier is
看7.1.6.2¶1(c ++ n3290),一个简单类型说明符是
A type-name is a class-name , an enum-name , a typedef-name , or a simple-template-id . 类型名称是类名称 , 枚举名称 , typedef名称或simple-template-id 。 The built-in primitive types do not fall in the category of a type-name .
内置基本类型不属于type-name的类别。 This means that the following will (and does) compile:
这意味着以下将(并确实)进行编译:
#include <string>
#include <iostream>
typedef int Int; // Now we can use ::Int because Int is a type-name.
using namespace std;
int main() {
const::Int i = 42; // No error.
const::string str = "Foo"; // No error.
cout << i << ' ' << str << '\n';
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.