類模板的模板友元函數定義有2種方式:
1. 將友元模板函數直接定義在類模板中。這種方式比較簡單直接。
2. 將友元模板函數聲明在類模板中,定義在類模板之外。這種方式的寫法,如果不小心,通常會出現編譯沒問題,鏈接時無法解析的錯誤。
以下是一個簡單的正確的例子:
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 +=被定義在類模板內部。其他3個函數先被聲明(需提前聲明類模板,如果模板函數的參數中含有類模板),然后在類模板中被聲明為友元函數, 之后被定義在類模板體之外。
2) 請注意當模板函數被聲明為類模板的友元時,在函數名之后必須緊跟模板實參表,用來代表該友元聲明指向函數模板的實例。否則友元函數會被解釋為一個非模板函數,鏈接時無法解析。
3) 友元模板函數的模板參數類型,并不一定要求是類模板的參數類型,也可以另外聲明。