我们来看下面的代码:
#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-expression”。
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'
答案 0 :(得分:7)
const::string
被解析为const ::string
。 ::string
表示在全局命名空间中查找string
,并且由于您已将std
注入全局命名空间,因此找到std::string
并且一切都很花哨。
int
是一种内置类型,并且不在任何命名空间中,因此不存在::int
或std::int
这样的错误。
答案 1 :(得分:3)
::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";
}
答案 2 :(得分:1)
它编译因为
using namespace std;
将整个std
命名空间拉入全局命名空间,因此::string
与std::string
相同。您的相关行实际上被解释为
const ::string str = "Foo";
但是,int
是关键字(和基本类型),而不是驻留在任何命名空间中的用户定义的名称。所以::int
没有意义。
答案 3 :(得分:0)
你的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
之间也没有区别
::
,::std::
和std::
都是嵌套名称说明符的示例,在c ++的5.1.1¶8中有描述n3290(C ++ 11标准的草案)。 const
是一个关键字,不能将其解释为嵌套名称说明符的主要部分。这意味着const::string
只能被解释为您已编写const ::string
。
在全局命名空间级别using namespace std;
的上下文中,使用::string
没有任何问题,因为前导::
意味着查找全局命名空间中的后续内容。您已将所有命名空间std
拉入全局命名空间。因此,const::string str
将str
声明为const
- std::string
类型的合格变量。
const::int i = 42;
怎么样?这种结构的标准中没有地方。看7.1.6.2¶1(c ++ n3290),简单类型说明符是
类型名称是类名,枚举名, typedef-name ,或 simple-template-id 。内置基元类型不属于类型名称的类别。这意味着以下将(并且确实)编译:
#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';
}