问题描述
我有一个看起来像这样的程序:
class B {};
class A
{
template<typename T> int operator+(const T&) const { return 1; } // Function 1
};
template<typename T,typename P> int operator+(const T&,const P&) { return 2; } // Function 2
int main()
{
A a;
B b;
std::cout<<(a + b);
return 0;
}
在这种情况下,将调用功能2。但是当我将函数1修改为自由函数而不是成员函数
template<typename T> int operator+(const A&,const T&) { return 1; } // Function 1
template<typename T,const P&) { return 2; } // Function 2
现在将调用功能1,即使在两种情况下功能1基本相同。这背后的原因是什么? GCC抱怨根据ISO C ++标准的模棱两可,但没有说明确切原因,反而可以很好地进行编译。这种情况对于运算符是唯一的,因为无论它们是否是成员,都可以用相同的方式调用它们。
解决方法
现在将调用功能1,即使在两种情况下功能1基本相同。背后的原因是什么?
Partial ordering of overloaded function templates用于在此处选择最佳匹配。
非正式地,“ A比B更专业”意味着“ A接受的类型少于B”。
功能1比功能2更专业,因为它接受的类型更少;它只能接受A
作为其第一操作数,而函数2可以接受任何类型。
出于相同的原因,在第一种情况下,成员功能1也应选择;就像clang一样。这似乎是gcc的错误,请参见Bug 53499和Bug 66914。