[英]Definition of class and variable with the same name
有這個代碼:
int x;
//void x(); // error: redefinition of 'x' as different kind of symbol
class x {}; // works ok
int main() {
return 0;
}
為什么定義具有相同名稱的變量和類是合法的,但定義具有相同名稱的變量和函數是不合法的?
第一種情況: 2個標識符
int x;
void x();
第二種情況: 1個標識符,1個類型名稱
int x;
class x {};
編譯器無法處理第一種情況,因為您有2個具有相同名稱的標識符,因此可能存在歧義。 (示例:嘗試獲取其中一個的內存地址。這是一種可能出現歧義的情況)
編譯器可以處理第二種情況,因為一種是類型而另一種是標識符,並且因為它知道在哪里期望類型以及在何處期望標識符,所以沒有歧義。
這是與C向后兼容所必需的(如果我記得,一些UNIX標頭定義了一個結構和一個具有相同名稱的變量)。
您可以消除類和變量/函數之間的歧義:
int x;
class x {};
int main()
{
x = 42; // global int x
//x obj; // error
class x obj; // use class-tag to disambiguate
}
但是你無法消除變量和函數之間的歧義。
另見Bjarne Stroustrup撰寫的“C ++的設計和演變”一書,§2.8.2。
這里發生的是C ++特有的。 隱藏了使用x
作為類名。
第3.3.7節(名稱隱藏)第2段:
類名(9.1)或枚舉名(7.2)可以通過在同一范圍內聲明的對象,函數或枚舉器的名稱隱藏。 如果類或枚舉名稱以及對象,函數或枚舉器在同一作用域(按任何順序)中聲明具有相同名稱,則在對象,函數或枚舉器名稱可見的任何位置都會隱藏類或枚舉名稱。
union
, enum
和struct
(我認為class
也是)一起從普通標識符中分離出“名稱桶”(與C ++名稱空間無關!)。 這在C中變得清晰,因為你必須在名稱前加上struct
等。
我沒有它用於C ++,但這是來自C標准:
6.2.3 Name spaces of identifiers
If more than one declaration of a particular identifier is visible at
any point in a translation unit, the syntactic context disambiguates uses
that refer to different entities.
Thus, there are separate name spaces for various categories of identifiers,
as follows:
— label names (disambiguated by the syntax of the label declaration and use);
— the tags of structures, unions, and enumerations (disambiguated by
following any32) of the keywords struct, union, or enum);
— the members of structures or unions; each structure or union has a
separate name space for its members (disambiguated by the type of the
expression used to access themember via the . or -> operator);
— all other identifiers, called ordinary identifiers (declared in ordinary
declarators or as enumeration constants).
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.