C++ 函数本地枚举声明与ADL的交互

C++ 函数本地枚举声明与ADL的交互,c++,c++14,language-lawyer,C++,C++14,Language Lawyer,命名空间X中的函数通过自动推导的返回类型从本地定义的枚举类返回枚举数。然后将该返回值传递给非限定函数,在g++(7.3、8.2、trunk)上,它在名称空间X中找到该函数。在clang上,它给出了未找到该函数的错误 我假设这与ADL以及函数本地声明的枚举是否在函数的包含命名空间中有关 哪个编译器是正确的,为什么?(欢迎标准引文。) 名称空间X{ 模板 EnumT getA(EnumT){ 返回EnumT::A; } 枚举类Foo{B,A,C}; 自动getLocalEnumerator(){ 枚

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

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

哪个编译器是正确的,为什么?(欢迎标准引文。)

名称空间X{
模板
EnumT getA(EnumT){
返回EnumT::A;
}
枚举类Foo{B,A,C};
自动getLocalEnumerator(){
枚举类条{A,B,C};
返回条::C;
}
}
int main(){
auto e1=X::Foo::C;//在命名空间X中明确
auto e2=X::getLocalEnumerator();//不确定这是什么名称空间
auto a1=getA(e1);//ADL的明显使用
自动a2=getA(e2);//叮当声:错误,g++:ADL正常
}
活在锁销上:

谢谢

这是一个叮当作响的错误。发件人:

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

本地枚举
Bar
将最内层的封闭命名空间作为其关联命名空间。。。这是
X
。对
getA
的非限定查找没有找到任何内容,因此我们继续查找所有参数的所有相关名称空间-相关名称空间集是
{X}
。在那里查找应该找到
X::getA

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
}