[英]Name lookup of first namespace name in nested-name-specifier?
給定一個沒有任何類,模板,枚舉或typedef的轉換單元中的嵌套名稱說明符A::
如果格式正確,則標識符A
必須引用名稱空間。
例如:
namespace X
{
int i;
}
int main()
{
X::i = 42; // Here X:: is a nested-name-specifier
// and X is a namespace-name
// i is looked up qualified w.r.t. X
}
在上面的例子中, A
是X
,但我的問題是關於一般情況。
如何在A::
為名稱空間名稱A
進行名稱查找?
名稱查找規則在3.4中進行了總結,但我不清楚在這種情況下如何(或哪些)適用。
例如,查找A
是不合格的名稱查找? 3.4.1是否適用於它?
換句話說:在名為A
的名稱空間中搜索哪些名稱空間,順序是什么? 你是如何從標准中得出結論的?
是的, A
是每個3.4.1的常規非限定名稱查找,連續搜索包含嵌套名稱說明符的作用域,但只能找到類和名稱空間名稱。 例如,你可以這樣:
int main()
{
int X;
X::i = 42; // OK, int X not found.
}
實際上不建議使用這個漏洞; 如果X
是類類型的對象,那么X::i
和Xi
可能是完全不同的東西。
為了從標准得出這個結論,從3.4.3開始(合格查找,這是我們最終分析的高級結構),在第1段中說明,
在將:: scope resolution運算符(5.1)應用於表示其類,名稱空間或枚舉的嵌套名稱說明符之后,可以引用類或名稱空間成員或枚舉數的名稱。 如果嵌套名稱說明符中的:: scope resolution運算符前面沒有decltype-specifier,則查找此前面的名稱::僅考慮其專門化為類型的名稱空間,類型和模板。 如果找到的名稱未指定名稱空間或類,枚舉或依賴類型,則程序格式錯誤。
閱讀第2段,它不適用,因為未聲明qualified-id。 其余段落同樣指明了不適用的例外情況。 那么, ::
之前的事情是什么? 參考語法。
nested-name-specifier:
::
type-name ::
namespace-name ::
decltype-specifier ::
nested-name-specifier identifier ::
nested-name-specifier templateopt simple-template-id ::
只有type-name ::
和namespace-name ::
匹配我們的先驗條件。 這些也與我們迄今為止發現的內容重疊。 通常如何在特定上下文中解析type-name
或namespace-name
? 不合格的查找。 進入3.4.1。
首先,3.4.1 / 1是一個要記住的一般規則:
在3.4.1中列出的所有情況下,在每個相應類別中列出的順序中搜索范圍; 一旦找到名稱的聲明,名稱查找就會結束。 如果沒有找到聲明,該程序就是格式錯誤。
下一個適用的段落是6:
在函數的declarator-id之后的函數定義中使用的名稱是名稱空間N的成員(其中,僅用於說明的目的,N可以表示全局作用域),應在其在塊中使用之前聲明它在其中一個封閉塊(6.3)中使用,或者在它在命名空間N中使用之前聲明,或者,如果N是嵌套命名空間,則應在N的封閉命名空間之一之前聲明它。
此規則並未告訴我們實際在全局命名空間中搜索名稱,但它確實在列表中提到了函數的封閉命名空間(在本例中為全局命名空間),而段落1則表示要搜索列出的命名空間。 這足以構建名稱查找。
令人驚訝的是,它沒有提到遞歸搜索優先考慮內部封閉的命名空間,但實際上你沒有在你的例子中有這樣的東西所以我會停在這里:)。 將編譯保留到編譯器要快得多,並且僅在出現問題時才能手動工作。
在您給出的示例中, X
將被視為非限定名稱查找。 因此它確實遵循3.4.1中的規則
在這種情況下,搜索的名稱空間如下:
main()
函數的本地命名空間。 (根據7.3.1.4,可能沒有定義名稱空間。) 我擔心我不能指向標准中的某個位置,它明確指出命名空間名稱與任何其他名稱相同。 但他們是。 名稱查找不知道它是名稱空間名稱(它可以是類名稱或結構名稱),直到它實際找到具有該名稱的名稱空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.