模板类在包含友元情况下的分离编写
此案例为模板类的分离编译,以及类中包含友元的情况是出现的错误及改正措施。
#include<iostream> #include<string> using namespace std; template<class T> class Person { public: //template<class T> friend ostream& operator<< <T>(ostream &os, Person<T>& p); //template<class T> friend void PrintPerson(Person<T>& p); Person(T age, T ID); void Show(); private: T mAge; T mID; }; template<class T> Person<T>::Person(T age, T ID) { this->mAge = age; this->mID = ID; } template<class T> void Person<T>::Show() { cout << "age:" << mAge << " ID:" << mID << endl; } //"<<"操作符重载 template<class T> ostream& operator<<(ostream &os, Person<T>& p) { os<< "age:" << p.mAge << " ID:" << p.mID ; return os; } //普通友元函数 template<class T> void PrintPerson(Person<T>& p) { cout << "age:" << p.mAge << " ID:" << p.mID << endl; } void test01() { Person<int> p(12, 12121200); cout << p << endl; cout << "-----------------------------" << endl; PrintPerson(p); } int main() { test01(); return 0; }
此时无法通过编译:显示以下错误:
严重性 代码 说明 项目 文件 行 错误 LNK1120 1 个无法解析的外部命令 类模板外部实现 D:\Documents\Visual Studio 2015\Projects\C++STL-Test\Debug\类模板外部实现.exe 1
严重性 代码 说明 项目 文件 行 错误 LNK2019 无法解析的外部符号 "void __cdecl PrintPerson(class Person<int> &)" (?PrintPerson@@YAXAAV?$Person@H@@@Z),该符号在函数 "void __cdecl test01(void)" (?test01@@YAXXZ) 中被引用 类模板外部实现 D:\Documents\Visual Studio 2015\Projects\C++STL-Test\类模板外部实现\mian.obj 1
解决方案为:在文件开始处添加以下声明。
//官方解决方案: template <class T> class Person; template <class T> void PrintPerson(Person<T>& p);
也可在普通友元声明前增加模板声明,此方法可能在其他编译器无法通过编译,如在Linux中无法通过编译。
//此方法无法在Linux下通过编译 template<class T> friend void PrintPerson(Person<T>& p);
综上,在模板中不要滥用友元。