【问题标题】:Interaction of function-local enum declaration and ADL函数局部枚举声明与 ADL 的交互
【发布时间】:2018-08-15 22:54:26
【问题描述】:

命名空间 X 中的函数通过自动推导的返回类型从本地定义的枚举类返回枚举数。然后将该返回值传递给一个不合格的函数,并在 g++ (7.3, 8.2, trunk) 上找到命名空间 X 中的函数。在 clang 上,它给出了找不到函数的错误。

我认为这与 ADL 以及函数本地声明的枚举是否在函数的包含命名空间中有关。

哪个编译器是正确的,为什么? (标准引用表示赞赏。)

namespace X {

      template <typename EnumT>
      EnumT getA(EnumT) {
          return EnumT::A;
      }

      enum class Foo { B, A, C };

      auto getLocalEnumerator() {
          enum class Bar { A, B, C };
          return Bar::C;
      }
}

int main() {
   auto e1 = X::Foo::C;               // unambiguously in namespace X
   auto e2 = X::getLocalEnumerator(); // unsure what namespace this is

   auto a1 = getA(e1);                // obvious use of ADL
   auto a2 = getA(e2);                // clang: error, g++: ADL ok
}

住在 Godbolt 上:https://godbolt.org/g/w2DhDm

谢谢!

【问题讨论】:

    标签: c++ c++14 language-lawyer


    【解决方案1】:

    这是一个clang错误。来自[basic.lookup.argdep]/2

    命名空间和类的集合按以下方式确定: [...] 如果 T 是枚举类型,则其关联命名空间是其声明的最内层封闭命名空间。如果是类成员,则其关联的类就是该成员的类;否则它没有关联的类。

    本地枚举Bar 具有作为其关联命名空间的最里面的封闭命名空间...X。对getA 的非限定查找一无所获,因此我们继续查看所有参数的所有关联命名空间 - 关联命名空间集是 {X}。在那里查找应该找到X::getA

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-26
      • 1970-01-01
      • 1970-01-01
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多