先看个代码:
#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
}
本文探讨了在C++中模板类的友元函数声明与实现的问题,特别是当友元函数为非模板函数时需要先进行声明才能正确编译的情况,并通过示例代码解释了原因。
8949

被折叠的 条评论
为什么被折叠?



