Why is it allowed to have a variable with same name with a struct type only if it's not a template?
Why is this considered okay:
struct Foo {
int func(int) const;
};
struct Foo Foo;
but not this:
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
CodePudding user response:
According to the C Standard (C 20, 13 Templates) class template name shall be unique in its declarative region.
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.
So for example this declaration in main
template<bool x = true>
struct Foo {
int func(int) const;
};
int main()
{
struct Foo<> Foo;
}
will be correct.
As for these declarations
struct Foo {
int func(int) const;
};
struct Foo Foo;
then the declaration of the variable Foo
hides the name of the declared structure. In C structure tag names and variable names are in different name spaces. So to preserve the compatibility with C such declarations in C are allowed.
To refer to the structure type after the variable declaration you need to use the elaborated name of the structure type.