[英]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.