我不知道为什么gcc会编译此代码
#include <type_traits>
template<class Type, class ValueT>
class ImplAdd
{
template<typename T>
friend typename std::enable_if<std::is_same<T, ValueT>::value, Type>::type
operator+(T, T)
{
return Type{};
}
};
enum class FooValueT { ONE, ZERO };
class Foo : ImplAdd<Foo, FooValueT>
{
public:
Foo() {}
Foo(FooValueT) {}
};
struct A {};
int main()
{
Foo f = FooValueT::ONE + FooValueT::ZERO;
}
clang和msvc无法编译,在我看来,它们是正确的。是GCC编译器中的错误吗? gcc的版本是4.8.2。
问题是由我的问题引起的:In-class friend operator doesn't seem to participate in overload resolution,答案中有来自标准的引号,指出该定义应在类范围内,并且如果函数不是模板-gcc拒绝此代码,那是正确的。感谢您的回答,并引用标准的引号,以证明gcc是正确的(或不正确的)。
最佳答案
我会说GCC错误地接受了这一点。引用C++ 11,重点是:
命名空间成员资格,7.3.1.2/3
与参数有关的查找,3.4.2 / 2:
3.4.2 / 4:
基于上述情况,我认为FooValueT
(FooValueT::ONE
和FooValueT::TWO
的类型)具有::
作为关联的 namespace ,但是没有关联的类(因为它是枚举)。因此,在ADL期间不应考虑在类模板ImplAdd
中定义的 friend 功能。