类的成员是否可以与其类型(另一个类)命名相同的名称?

chr*_*ris 9 c++ implementation g++ clang visual-c++-2012

尝试在不同的编译器上编译以下代码给我两个不同的结果:

struct S{};
struct T{S S;};
int main(){}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在内部T,我有一个与之前定义的类名称相同的对象S.


在GCC 4.7.2上,我收到S S;内部声明有关的以下错误T:

错误:声明'ST :: S'[-fpermissive]
错误:从'struct S'改变'S'的含义[-fpermissive]

但是,将它移到课堂外(或进入main)可以正常工作:

struct S{};
S S;
int main(){}
Run Code Online (Sandbox Code Playgroud)

它给我的错误究竟是什么意思?


在Visual Studio 2012中,整个事件编译并运行没有任何错误.将它粘贴到这个Clang 3.0编译器中也没有错误.

哪个是对的?我真的可以这样做吗?

Jes*_*ood 14

gcc是正确的,来自[3.3.7类范围]

在类S中使用的名称N应在其上下文中引用相同的声明,并在完成的S范围内重新评估.违反此规则不需要诊断.

但请注意no diagnostic is required,所有编译器都符合要求.

原因是因为课程范围如何运作.当您S S; S整个班级中可见时,您可以在使用时更改其含义S.

struct S{};
struct T{
    void foo()
    { 
        S myS; // Not possible anymore because S refers to local S
    }
    S S;
};
Run Code Online (Sandbox Code Playgroud)

  • IIRC 的基本原理是允许在类内部定义类成员函数。如果名称的含义在类中发生变化,那么在它们内部查找名称会很奇怪。(按原样已经够难了)。 (2认同)

Joh*_*itb 6

此代码格式错误,无需诊断.就像诊断所说的那样,如果一个声明使用了一个名称,并且该名称的含义与在类定义末尾查找时的含义不同,则该程序不正确,无需诊断.


Big*_*oss 6

@JesseGood提供了一个完整的答案,但是如果你真的想这样做而没有任何错误,你可以使用类型的全名,它将按如下方式工作:

struct S {};
struct T { ::S S; };
int main() {return 0;}
Run Code Online (Sandbox Code Playgroud)

不,没有错误,因为S在你的班级是T::S和它的类型::S!