c++模板的行为和操作符重载
Behavior of C++ templates and operator overloading
我想了解下面的代码行为
#define USE_FRIEND
class Foo
{
public:
template <typename T>
Foo& operator<< (T val)
{
std::cout << "Inside Foo" << std::endl;
return *this;
}
};
class A
{
public:
#ifdef USE_FRIEND
friend Foo& operator<<(Foo& f, A& a)
{
std::cout << "Inside A" << std::endl;
return f;
}
#endif
};
int main()
{
A a;
Foo f;
#ifdef USE_FRIEND
std::cout << " using Friend :: ";
#else
std::cout << " not using Friend :: ";
#endif
f << a;
system("pause");
return 0;
}
上述代码两次执行的输出,一次带有Using友元,另一次没有:
案例1:
using Friend :: Inside A
案例2:
not using Friend :: Inside Foo
我能理解第二种情况,但有人能解释第一种情况吗
重载解析是一件复杂的事情,但这里有两个相关的规则:
-
可行的重载如下:
-
template <typename T> Foo & Foo::operator<<(T)
-
Foo & operator<<(Foo &, A &)
-
-
当调用
operator<<(f, a)
时,则两个重载匹配,并且它们都在鼻子上匹配,从而导出模板中的T = A
。在精确性上没有差别,因为引用被视为"完美匹配"。 -
因此这两个重载是绑定的,并且分辨率看起来是不明确的。然而,有一个决定性因素:第1条是模板,而第2条不是。在这种情况下,非模板是更好的匹配