函数-本地枚举声明和 ADL 的交互



命名空间 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
}

住在神霹雳上:https://godbolt.org/g/w2DhDm

谢谢!

这是一个叮当错误。从 [basic.lookup.argdep]/2:

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

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

最新更新