類(lèi)模板的模板友元函數(shù)定義有2種方式:
1. 將友元模板函數(shù)直接定義在類(lèi)模板中。這種方式比較簡(jiǎn)單直接。
2. 將友元模板函數(shù)聲明在類(lèi)模板中,定義在類(lèi)模板之外。這種方式的寫(xiě)法,如果不小心,通常會(huì)出現(xiàn)編譯沒(méi)問(wèn)題,鏈接時(shí)無(wú)法解析的錯(cuò)誤。
以下是一個(gè)簡(jiǎn)單的正確的例子:
1 #include <iostream>
2 #include <vector>
3
4 template <typename T>
5 class Number;
6
7 template <typename T>
8 void print(const Number<T>& n);
9
10 template <typename T>
11 std::ostream& operator << (std::ostream& os, const Number<T>& n);
12
13 template <typename T>
14 std::istream& operator>>(std::istream& is, Number<T>& n);
15
16 template <typename T, typename T2>
17 void printVector(const std::vector<T2>& vt, const Number<T>& n);
18
19 template <typename T>
20 class Number {
21 public:
22 Number(T v)
23 : val(v) {}
24 ~Number() {}
25
26 private:
27 T val;
28 public:
29 friend void print<T> (const Number<T>& n);
30 friend std::ostream& operator << <T>(std::ostream& os, const Number<T>& n);
31 friend std::istream& operator>> <T>(std::istream& is, Number<T>& n);
32
33 friend Number<T>& operator += (Number<T>& a, const Number<T>& b)
34 {
35 a.val += b.val;
36 return a;
37 }
38 template <typename T2>
39 friend void printVector<T>(const std::vector<T2>& vt, const Number<T>& n);
40 template <typename T2>
41 void memFunc(const std::vector<T2>& vt, const Number<T>& n);
42 };
43
44 template <typename T>
45 std::ostream& operator <<(std::ostream& os, const Number<T>& n)
46 {
47 os << n.val << std::endl;
48 return os;
49 }
50
51 template <typename T>
52 std::istream& operator >>(std::istream& is, Number<T>& n)
53 {
54 is >> n.val;
55 return is;
56 }
57
58 template <typename T>
59 void print<T> (const Number<T>& n)
60 {
61 std::cout << n;
62 }
63
64 template <typename T, typename T2>
65 void printVector(const std::vector<T2>& vt, const Number<T>& n)
66 {
67 for (unsigned int i = 0; i < vt.size(); i++)
68 std::cout << vt.at(i) << " ";
69 std::cout << "=> " << n;
70 }
71
72 template <typename T>
73 template <typename T2>
74 void Number<T>::memFunc(const std::vector<T2>& vt, const Number<T>& n)
75 {
76 for (unsigned int i = 0; i < vt.size(); i++)
77 std::cout << vt.at(i) << " ";
78 std::cout << "=> " << n;
79 }
80
1) 以上代碼中,operator +=被定義在類(lèi)模板內(nèi)部。其他3個(gè)函數(shù)先被聲明(需提前聲明類(lèi)模板,如果模板函數(shù)的參數(shù)中含有類(lèi)模板),然后在類(lèi)模板中被聲明為友元函數(shù), 之后被定義在類(lèi)模板體之外。
2) 請(qǐng)注意當(dāng)模板函數(shù)被聲明為類(lèi)模板的友元時(shí),在函數(shù)名之后必須緊跟模板實(shí)參表,用來(lái)代表該友元聲明指向函數(shù)模板的實(shí)例。否則友元函數(shù)會(huì)被解釋為一個(gè)非模板函數(shù),鏈接時(shí)無(wú)法解析。
3) 友元模板函數(shù)的模板參數(shù)類(lèi)型,并不一定要求是類(lèi)模板的參數(shù)類(lèi)型,也可以另外聲明。