[英]Scope resolution operator and const
让我们看下面的代码:
#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?
}
为什么要编译此代码? 仅当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
被解析为const ::string
。 ::string
表示在全局名称空间中查找string
,并且由于您已将std
注入全局名称空间,因此找到了std::string
,并且所有操作都变得很花哨。
int
是内置类型,不在任何名称空间中,因此不存在::int
或std::int
的错误。
::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";
}
它之所以编译是因为
using namespace std;
将整个std
名称空间放入全局名称空间,因此::string
与std::string
相同。 您所讨论的行实际上被解释为
const ::string str = "Foo";
但是, int
是关键字(和基本类型),而不是驻留在任何名称空间中的用户定义名称。 所以::int
没有意义。
您正在using namespace std;
有点红鲱鱼。 注意const::std::string str = "Foo";
也可以编译。 之所以进行编译(以及您的const::string str = "Foo";
编译的原因)是因为::
是作用域解析运算符。 间距无关紧要。 就像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::
和std::
都是嵌套名称说明符的所有示例,在c ++ n3290(C ++ 11标准的草案)的5.1.1¶8中进行了描述。 const
是一个关键字,不能将其解释为nested-name-specifier的开头 。 这意味着const::string
只能像您已经写过const ::string
一样被解释。
在using namespace std;
的上下文中using namespace std;
在全局名称空间级别,使用::string
没什么问题,因为前导::
表示查找全局名称空间中的内容。 您已将所有名称空间std
放入全局名称空间。 因此const::string str
声明了str
作为const
-qualified类型的可变std::string
。
那么const::int i = 42;
? 在这种构造的标准中没有地方。 看7.1.6.2¶1(c ++ n3290),一个简单类型说明符是
类型名称是类名称 , 枚举名称 , typedef名称或simple-template-id 。 内置基本类型不属于type-name的类别。 这意味着以下将(并确实)进行编译:
#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.