类模板的模板友元函数定义(转载)

转自:http://www.cppblog.com/zerolee/archive/2010/11/03/132344.html

类模板的模板友元函数定义有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) 友元模板函数的模板参数类型,并不一定要求是类模板的参数类型,也可以另外声明。

posted on 2011-03-05 21:32  Pro.Charm  阅读(983)  评论(0编辑  收藏  举报

导航