先看个代码:
#include <list>
using namespace std;
template <class T>
class A
{
public:
friend bool operator== <> (const A&, const A&); //注意加<>
//friend bool operator== <T> (const A&, const A&); 可行
//friend bool operator== <T> (const A<T>&, const A<T>&); 可行
};
template <class T>
bool operator==(const A<T>&, const A<T>&)
{
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
A<int> a;
A<int> b;
a == b;
return 0;
}
编译-运行皆无问题。
但是,把#include <list>
using namespace std;去掉后编译出错,何解?
初次猜测总不至于list和std里有什么猫腻吧,后来细细想来,原来是这样。来看另外的代码:
template <class T>
bool operator==(const T&, const T&);
template <class T>
class A
{
public:
friend bool operator== <> (const A&, const A&);
};
template <class T>
bool operator==(const A<T>&, const A<T>&)
{
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
A<int> a;
A<int> b;
a == b;
return 0;
}
编译运行皆无问题,哈哈,发现问题所在了吧,必须在模板类声明此友元函数之前必须要有这个函数的声明,不然编译器不认。而在list std里可能就有了如红色标明的全局的==重载声明,以致于在不自觉中声明了函数,呵呵。
NOTE:只有在模板类中声明友元时,如果不在声明时定义的话,你就必须在之前给这函数进行声明。但是如果不是模板类的话则不需要预先声明。代码如下:
class C
{
private:
int i;
public:
friend void func(const C&);
};
void func(const C& c) { printf("%d", c.i);}
int _tmain(int argc, _TCHAR* argv[])
{
func(C()); // OK ,not error
}