簡體   English   中英

范圍解析運算符和const

[英]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是內置類型,不在任何名稱空間中,因此不存在::intstd::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名稱空間放入全局名稱空間,因此::stringstd::string相同。 您所討論的行實際上被解釋為

const ::string str = "Foo";

但是, int是關鍵字(和基本類型),而不是駐留在任何名稱空間中的用戶定義名稱。 所以::int沒有意義。

您正在using namespace std; 有點紅鯡魚。 注意const::std::string str = "Foo"; 也可以編譯。 之所以進行編譯(以及您的const::string str = "Foo";編譯的原因)是因為::是作用域解析運算符。 間距無關緊要。 就像a+b+ca + b + c之間沒有區別一樣, const::string strconst :: string str之間也沒有區別(同樣, const::std::string strconst :: 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),一個簡單類型說明符

  • 類型名稱 ,可以選擇在其后加一個嵌套名稱說明符
  • 嵌套名稱說明符 模板 simple-template-id
  • 內置原始類型之一,
  • auto關鍵字,或
  • 十進制類型說明符

類型名稱類名稱枚舉名稱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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM