C ++别名具有相同名称的类型

C++ Aliasing a type with the same name

考虑以下代码:

class A {};

class B {
  using A = A;
};

使用 Clang 和 ICC 编译正常,而 GCC 失败并显示以下消息:

error: declaration of ‘using A = class A’ changes meaning of ‘A’ [-fpermissive]
    4 |   using A = A;
      |         ^

问题:哪个编译器是正确的,为什么?

Clang 和 ICC 是对的。

[basic.scope.pdecl]

3 ... The point of declaration of an alias or alias template immediately follows the defining-type-id to which the alias refers.

别名声明的语法是

[dcl.pre]

1 ...

alias-declaration:
using identifier attribute-specifier-seqopt = defining-type-id ;

因此 A 的“新”含义直到 声明中仍然指代“旧” [=11] 的部分之后才正式声明=].

现在,这并不是说这里没有潜力问题。因为我们还有

[basic.scope.class]

2 A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

你写了吗:

class A {};

class B {
  A a;
  using A = A;
};

我们现在有 A 引用了第一次使用和完整的 class 范围之间的不同声明。当然,它是被命名的同一类型,但通过不同的声明。这足以使代码成为格式错误的 NDR。 GCC 可能有一种启发式方法来保护代码免受此影响。这是被你的良性例子绊倒了。