几个关键点:
需要前置声明!--奇怪的是别人告诉我也可以不需要,但我这里不行!
友元函数的函数名后面的<>,必须要有。
1 #include <stdio.h> 2 #include <iostream> 3 using namespace std; 4 5 //前置声明,你妹啊 6 template<class T> class A; 7 template<class T> ostream &operator<< (ostream &out, const A<T> &_a); 8 template<class T1, class T2> class B; 9 template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b); 10 11 template<class T> class A 12 { 13 public: 14 A(){} 15 A(T _a, T _b):a(_a),b(_b){} 16 ~A(){} 17 private: 18 T a; 19 T b; 20 21 friend ostream &operator<< <> (ostream &out, const A<T> &a); 22 }; 23 24 template<class T> ostream &operator<< (ostream &out, const A<T> &_a){ 25 out<<_a.a<<"--"<<_a.b; 26 return out; 27 } 28 29 template<class T1, class T2> class B: public A<T1> 30 { 31 public: 32 B(){} 33 B(T1 _a, T1 _b, T2 _c):A<T1>(_a,_b),c(_c){} //A<T1> 34 ~B(){} 35 private: 36 T2 c; 37 38 friend ostream &operator<< <>(ostream &out, const B<T1, T2> &_b); 39 }; 40 template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b){ 41 // out<<(A<T1>)_b; 42 // out<<"--"<<_b.c; 43 44 out<<(A<T1>)_b<<"--"<<_b.c; 45 return out; 46 } 47 48 int main(int argc, char const *argv[]) 49 { 50 A<int> x(1, 3); 51 B<char, int> y('a', 'b', 5); 52 53 cout<< x <<endl; 54 cout<< y <<endl; 55 56 return 0; 57 }
以上认识太片面,请忽略。
这里 有完美的解释!
大意如下:
模板类的友元其实有多个可能,关键在于这个友元是该模板类的一个/特定具现(实例)的友元,还是所有具现(实例)的友元。
注意1,这里不需要考虑与泛型无关的友元--例如输出一句话之类的,完全没有意义。
注意2,这里的多个可能是编译之前的可能,编译之后还是一个具现(实例)有一个友元(---猜测)。
总之,我认为,这两种仅仅是出发点不同,但最终目的地一致。
一、友元是模板类的一个/特定具现(实例)的友元,需要前置声明:
#include <stdio.h> #include <iostream> using namespace std; //前置声明,你妹啊 template<class T> class A; template<class T> ostream &operator<< (ostream &out, const A<T> &_a); template<class T1, class T2> class B; template<class T1, class T2> ostream &operator<< (ostream &out, const B<T1, T2> &_b); template<class T> class A { public: A(){} A(T _a, T _b):a(_a),b(_b){} ~A(){} private: T a; T b; friend ostream &operator<< <> (ostream &out, const A<T> &a); }; template<class T> ostream &operator<< (ostream &out, const A<T> &_a){ out<<_a.a<<"--"<<_a.b; return out; } int main(int argc, char const *argv[]) { A<int> x(1, 3); cout<< x <<endl; return 0; }
二、友元是所有具现(实例)的友元,不需要前置声明:
#include <iostream> using namespace std; //友元operator<< 是模板类A的所有实例的友元(实际上还是多个operator<<)--不需要前置声明。 template <typename T> struct A { T a; A(T _a) :a(_a) {} template <typename T1> friend ostream &operator<< (ostream &out, const A<T1> &_a);//这里的T1?? 由于<<输出的是A的实例的对象,所以实际上这里的T1编译之后还是T--因为编译器找不到其他可能。 }; template <typename T> ostream & operator<< (ostream & out, const A<T> &_a) { out << _a.a; return out; } int main() { A<int> x(15); cout << x << endl; return 0; }