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

发布于 2025-01-12 17:03:23 字数 999 浏览 0 评论 0原文

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

为什么这被认为是可以的:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

年少掌心 2025-01-19 17:03:23

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

7 类模板不得与任何其他模板同名,
类、函数、变量、枚举、枚举器、命名空间或类型
除 13.7.6 中规定的情况外,在同一范围(6.4)中。除了一个
函数模板可以被非模板函数重载
(9.3.4.6) 与其他函数模板同名或
相同的名称(13.10.4),在命名空间范围或中声明的模板名称
类范围在该范围内应是唯一的。

例如,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++ 中允许使用此类声明。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文