具有相同名称的类和变量的定义

时间:2013-05-16 16:39:23

标签: c++

有这段代码:

int x;

//void x(); // error: redefinition of 'x' as different kind of symbol

class x {}; // works ok

int main() {
   return 0;
}

为什么定义具有相同名称的变量和类是合法的,但定义具有相同名称的变量和函数是不合法的?

4 个答案:

答案 0 :(得分:13)

第一种情况: 2个标识符

int x;
void x();

第二种情况: 1个标识符,1个类型名称

int x;
class x {};

编译器无法处理第一种情况,因为您有2个具有相同名称的标识符,因此可能存在歧义。 (示例:尝试获取其中一个的内存地址。这是一种可能出现歧义的情况)

编译器可以处理第二种情况,因为一种是类型而另一种是标识符,并且因为它知道在哪里期望类型以及在哪里期望标识符,所以没有歧义。

答案 1 :(得分:5)

这是与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。

答案 2 :(得分:5)

这里发生的是C ++特有的。使用x作为类名是隐藏的。

第3.3.7节(名称隐藏)第2段:

  

类名(9.1)或枚举名(7.2)可以通过在同一范围内声明的对象,函数或枚举器的名称隐藏。如果类或枚举名称以及对象,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则在对象,函数或枚举器名称可见的任何位置都隐藏类或枚举名称。 / p>

答案 3 :(得分:2)

unionenumstruct(我也认为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).