我不知道为什么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::ONEFooValueT::TWO的类型)具有::作为关联的 namespace ,但是没有关联的类(因为它是枚举)。因此,在ADL期间不应考虑在类模板ImplAdd中定义的 friend 功能。

10-04 13:39