【问题标题】:Hiding names with 'using' directive使用“使用”指令隐藏名称
【发布时间】:2020-08-10 19:24:54
【问题描述】:

代码示例:

struct A {};
struct B { using A = A; };

int main()
{
    B b;
}

Clang 编译它。但是 GCC 给出了以下错误(demo):

“使用 A = struct A”的声明改变了“A”的含义

C++ standard 说:

如果类名 ([class.name]) 或枚举名 ([dcl.enum]) 和变量、数据成员、函数或枚举数在同一个声明区域中声明(以任何顺序)具有相同名称(不包括通过 using-directives 可见的声明 ([basic.lookup.unqual])),无论变量、数据成员、函数或枚举器名称如何,类或枚举名称都隐藏可见。

UPD.0:感谢来自莫斯科的 Vlad

在类 S 中使用的名称 N 应在其上下文中引用相同的声明,并且在 S 的完整范围内重新评估时。违反此规则不需要诊断

这是否意味着 GCC 行为不正确?谢谢!

【问题讨论】:

  • 你的引用是关于一个“变量、数据成员、函数或枚举器”隐藏了一个类名,这里不是这样,所以你可能需要看看别处在标准中。而这里的"using-directives"似乎指的是using namespace:eel.is/c++draft/namespace.udir#nt:using-directive
  • @Holt,感谢您的回答,但您提供的链接仅与命名空间有关。
  • 完整阅读我的评论,而不仅仅是链接...我的意思是,您对标准的引用与这里无关,原因有两个:1)它不包含任何关于隐藏其他类的类名名称,2) using-directives 指的是命名空间,而不是 using =,它们被标准命名为不同的名称:eel.is/c++draft/dcl.typedef 关键字 using 在 C++ 中的 3 种不同情况下使用,所以在查找与using 相关的标准时,您必须小心。
  • @Holt,好的,我明白了。感谢您的解释!我将编辑如何在 C++ 标准中找到必要的段落的问题。
  • @LanguageLawyer,是的,谢谢,这似乎是同一个问题。

标签: c++ language-lawyer


【解决方案1】:

好像是gcc的bug。根据 C++ 20 标准(6.3.7 类范围)

2 在类 S 中使用的名称 N 应引用相同的声明 它的上下文以及在 S 的完整范围内重新评估时。否 违反此规则需要进行诊断。

在这种情况下

struct A {};
struct B { using A = A; };

名称B::A指的是struct A的同一个声明。

这是一个来自 C++ 标准的示例,显示了引号的含义。

typedef char* T;
struct Y {
   T a; // error: T refers to ::T but when reevaluated is Y::T
   typedef long T;
   T b;
};

【讨论】:

  • 这也是我的结论。更多证据:1)using A = A;struct B 之外工作得非常好,2)using A2 = A;struct B 之前然后using A = A2;struct B 中也可以工作(所以隐藏名称@987654331 不是问题@), 3) std::is_same_v<A2, A>struct B 中为真(所以A 不是它的样子不是问题)。
  • 重新评估using A = A; 正确吗?而不是评估using A = B::A;?
  • 请注意,示例中的错误注释并不是说T在重新评估时指的是不同的类型,而是表示不同的声明
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-23
  • 2012-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多