【问题标题】:Ambiguous name lookup with C++20 using-enum-declaration使用 C++20 using-enum-declaration 进行模糊名称查找
【发布时间】:2021-07-09 18:53:33
【问题描述】:

考虑以下代码 sn-p 与 C++20 using-enum-declaration:

namespace A { enum A {}; };

using namespace A;
using enum A;

gcc-trunk rejects 它与:

<source>:4:12: error: reference to 'A' is ambiguous
    4 | using enum A;
      |            ^
<source>:1:20: note: candidates are: 'enum A::A'
    1 | namespace A { enum A {}; };
      |                    ^
<source>:1:11: note:                 'namespace A { }'
    1 | namespace A { enum A {}; };
      |           ^
<source>:4:12: error: 'A' has not been declared
    4 | using enum A;
      |            ^

但是,msvc 接受它。有趣的是,如果我为 enum A 添加命名空间限定符:

namespace A { enum A {}; };

using namespace A;
using enum A::A;

gcc 接受这一次,但 msvc rejects 它与:

<source>(4): error C2872: 'A': ambiguous symbol
<source>(1): note: could be 'A'
<source>(1): note: or       'A::A'

哪个编译器是正确的?

【问题讨论】:

    标签: c++ language-lawyer c++20 name-lookup using-declaration


    【解决方案1】:

    gcc 在这里出错(提交100'084)。

    using enum A; 的语法来自[enum.udecl]

    使用枚举声明

        using 详细枚举说明符 ;

    [basic.lookup.elab]中定义了查找这样的东西:

    如果 elaborated-type-specifier 中的 class-keyenum 关键字后面跟着一个未跟随的 identifier通过​::​,标识符的查找是仅类型([basic.lookup.general])。

    elaborated-enum-specifierelaborated-type-specifier 的一种,所以我们只进行类型查找。在[basic.lookup.general]/4中定义为:

    但是,如果查找是type-only,则只考虑类型和特化为类型的模板的声明;此外,如果找到 typedef-name 及其引用的类型的声明,则丢弃 typedef-name 的声明而不是类型声明。

    这意味着当我们查找A 时,我们同时找到enum Anamespace A,因为我们的查找是仅类型的,我们只考虑前者而不考虑后者。结果,我们只有一个候选人,这就是我们的查找找到的候选人。没有歧义。

    【讨论】:

      【解决方案2】:

      MSVC 在这里是正确的。第一种情况是仅类型查找(因为它被认为是详细的类型说明符),因此它忽略命名空间并通过 using-directive 查找枚举。在第二种情况下,下面的:: 允许找到命名空间,所以它是模棱两可的。

      【讨论】:

      • 等待第二种情况是 supposed 模棱两可吗?我喜欢这种语言。我认为它是如此“明显”,以至于我什至没有写第二个 MSVC 是错误的......
      • @Barry gcc 好像很久以前就有这个issue了。
      • @Barry:您可以对任何枚举进行合格的查找。像往常一样,没有考虑到您不可能在那里找到一个可以作为 详细类型说明符 的有效主题的实体这一事实。
      猜你喜欢
      • 2015-10-16
      • 1970-01-01
      • 2013-07-03
      • 1970-01-01
      • 2018-08-04
      • 1970-01-01
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      相关资源
      最近更新 更多