在下面的代碼片段中,我可以理解(從§3.3.2/ 6第二個要點),聲明struct B* p;
中的名稱B
作爲的類名稱被注入到全局名稱空間中。我對§3.3.2/ 6中的'first'這個詞的解釋是否正確?
struct A {
// struct B{};
int B;
struct B* p;
};
void f(B&) {}
int main()
{
A a;
f(*a.p);
}
§3.3.2/ 6:
一類第一在 聲明的聲明的點闡述型說明符如下:
申請表格
class-keyattribute-specifier-seqoptidentifier;
的標識符被聲明爲在 包含聲明的範圍類名,否則
用於闡述型說明符形式的
class-key標識符
如果詳細制定型說明符在DECL說明符-SEQ或參數聲明子句中的命名空間範圍內定義的函數的中所使用的,標識符被聲明爲 類名在包含聲明的名稱空間中;否則,除了作爲的朋友聲明,標識符是 聲明在包含 聲明的最小名稱空間或塊範圍內。 [注意:這些規則也適用於模板。 - 年底 注] [注:中其他形式闡述類型說明符不 宣佈一個新的名稱,因此必須引用現有的類型名稱。 見3.4.4和7.1.6.3。 - 注完]
但是,如果我去掉裏面struct A
的的struct B{};
定義,我剛纔對於注射名字B
到全局命名空間中說,已經不發生,如代碼不能編譯。我認爲這需要做上面的字第一(重點煤礦),因爲現在類名B
,在申報struct B* p;
不再是它的第一個聲明在其聲明區。我正確地說這個嗎?
假設我的解釋是正確的,爲什麼在這種情況下類名B
沒有注入到全局名稱空間中?請注意,在這種情況下,嵌套類struct B{};
將隱藏在A內部,即,即使我們將函數f
的聲明更改爲void f(A::B&)
,代碼也不會編譯。
還有一點我不清楚:是什麼讓實現者決定將類名注入命名空間,或者在第二個項目符號中包含詳細類型說明符的塊範圍點以上?也就是說,他們爲什麼不把類名聲明留在類範圍內?
注入封閉名稱空間肯定是爲了與C兼容。 – avakar 2014-10-02 20:01:28
您可以多探索一下嗎? – 2014-10-02 20:07:05
C沒有類/結構作用域,因此,struct S {struct X {int y; }; int x; }; struct X my_var = {42};'在C中是合法的(呃,它很醜 - 但它實際上是用clang和gcc編譯的,儘管後者有一個警告)。 – dyp 2014-10-02 20:19:12