【转】模板类里声明友元函数---链接器错误 LNK2001
错误消息
在函数“function”中引用了无法解析的外部符号“symbol”
在 function 中找到了未定义的外部符号 (symbol)。若要解决此错误,请提供符号定义或移除引用它的代码。一般报错如下:
error LNK2001: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Array<class Animal> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Array@VAnimal@@@@@Z)
#include <iostream>
using namespace std;
template<class T> class
Test {
friend ostream& operator<<(ostream&, Test&);
// 注意,将上面一行换作下面任意一行就可以解决此问题。
// 区别在于,在友元函数声明之前添加template<typename T> 以帮助编译器了解友元函数的类型?
// template<typename T> friend ostream& operator << (ostream&, Test<T>&); //第一种改法
// friend ostream& operator << <>(ostream&, Test<T>&); //第二种改法
// friend ostream& operator << <T>(ostream&, Test<T>&); //第三种改法
};
template<typename T>
ostream& operator<<(ostream& os, Test<T>& tt) {
return os;
}
int main() {
Test<int> t;
cout << "Test: " << t << endl; // unresolved external
}
网上看到的一种改法,报error LNK2001: unresolved external symbol的错!因为没有像sun手册中提到的“实际的模板声明必须在友元声明之前”中讲到的“由于operator<<有一个type array<T>的参数(模板类型形参?),因此在声明函数之前,必须声明array<T>。”
#include <iostream>
using namespace std;
/* 通过和微软MSDN的比较,就可以发现:
* 事先在类声明之前声明其中的重载函数是没有用的
*/
//声明模板类
template <class T> class test;
//声明模板类中的重载函数,不过这句话貌似可有可无
template <class T> ostream& operator<<(ostream& os, const test<T>& des);
template <class T>
class test{
T x;
public:
friend ostream& operator<<(ostream& os, const test<T>& des);
//改成下面一行就可以了
//friend ostream& operator<< <T> (ostream& os, const test<T>& des);
};
template <class T>
ostream& operator<<(ostream& os, const test<T>& des)
{
return os << des.x;
}
int main(int, char* [])
{
test<int> x;
cout << x << endl; //未能解析的外部变量
return 0;
};
转自:http://blog.csdn.net/lychee007/article/details/4428487

浙公网安备 33010602011771号