名称空间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
谢谢!
答案 0 :(得分:4)
这是一个clang错误。来自[basic.lookup.argdep]/2:
以下列方式确定名称空间和类的集合:[...]如果T是枚举类型,则其关联的名称空间是其声明的最内部封闭的名称空间。如果是类成员,则其关联的类是成员的类;否则它没有关联的类。
本地枚举Bar
具有最里面的封闭命名空间... X
作为其关联的命名空间。在getA
上进行不合格的查找不会发现任何内容,因此我们继续查看所有参数的所有关联命名空间-关联命名空间的集合为{X}
。在此处查找应该找到X::getA
。