【转】模板类里声明友元函数---链接器错误 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


posted @ 2011-12-17 13:27  MagiCube  阅读(820)  评论(0编辑  收藏  举报