仅当它不是模板时才编译具有结构类型的同名变量

Variable with same name with a struct type compiling only if it's not a template

为什么只有在不是模板的情况下才允许具有结构类型的同名变量?

为什么这被认为是好的:

struct Foo {
    int func(int) const;
};

struct Foo Foo;

但不是这个:

template<bool x = true>
struct Foo {
    int func(int) const;
};

struct Foo<> Foo;
// gcc 11.2

<source>:6:14: error: 'Foo<> Foo' redeclared as different kind of entity
    6 | struct Foo<> Foo;
      |              ^~~
<source>:2:8: note: previous declaration 'template<bool x> struct Foo'
    2 | struct Foo {
      |        ^~~
Compiler returned: 1

// clang 13.0.1

<source>:6:14: error: redefinition of 'Foo' as different kind of symbol
struct Foo<> Foo;
             ^
<source>:2:8: note: previous definition is here
struct Foo {
       ^
1 error generated.
Compiler returned: 1

https://godbolt.org/z/s94n115fq

根据 C++ 标准(C++ 20、13 模板)class 模板名称在其声明区域中应是唯一的。

7 A class template shall not have the same name as any other template, class, function, variable, enumeration, enumerator, namespace, or type in the same scope (6.4), except as specified in 13.7.6. Except that a function template can be overloaded either by non-template functions (9.3.4.6) with the same name or by other function templates with the same name (13.10.4), a template name declared in namespace scope or in class scope shall be unique in that scope.

因此,例如 main

中的这个声明
template<bool x = true>
struct Foo {
    int func(int) const;
};

int main()
{
    struct Foo<> Foo;
}

将是正确的。

至于这些声明

struct Foo {
    int func(int) const;
};

struct Foo Foo;

那么变量的声明Foo隐藏了声明结构的名称。在 C 结构中,标记名称和变量名称位于不同的名称空间中。因此,为了保持与 C 的兼容性,允许在 C++ 中进行此类声明。

要在变量声明后引用结构类型,您需要使用结构类型的详细名称。