class 名称和同名变量的声明

Declarations of a class name and a variable with the same name

标准N4296::3.3.1/4 [basic.scope.declarative]:

exactly one declaration shall declare a class name or enumeration name that is not a typedef name and the other declarations shall all refer to the same variable or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is hidden (3.3.10).

我知道这条规则是关于隐藏 class 的名称,如果在同一个声明区域中有同名的 variable/function 声明。但是 exactly one 有点令人困惑。以下命名空间完全有效:

namespace A
{
    struct A;
    struct A { };
    int A;
}

DEMO

尽管我们声明了 struct A 两次(两次声明一个结构,一次声明变量)。怎么了?我在规则中失去了什么?

struct A; 是一个声明。然而,struct A { };定义

// Exactly one class may have the name:
struct A; // Declaration of a new class.
struct A { }; // Definition, but not a declaration of a new name. Doesn't count.

// Aside from the class, exactly one variable may share the name:
extern int A; // Declaration of a variable.
int A; // Definition of a variable.