惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The GitHub Blog
The GitHub Blog
MyScale Blog
MyScale Blog
爱范儿
爱范儿
GbyAI
GbyAI
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
美团技术团队
Y
Y Combinator Blog
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
M
MIT News - Artificial intelligence
博客园 - Franky
V
Visual Studio Blog
I
InfoQ
V
V2EX
Hugging Face - Blog
Hugging Face - Blog
腾讯CDC
博客园 - 司徒正美
L
LangChain Blog

博客园 - Zero Lee

调用栈(call stack) 关于STL allocator Calculate maximum sum of any subarray set Calcuate power n of x recursively Convert one binary search tree to double-linked list 设计包含min函数的栈 一道百度的面试题解答 非printf形式的十六进制和二进制打印(雅虎面试题) 一道腾讯面试题 (转)C++中extern “C”含义深层探索 selection algorithm to select nth small elements based on partition 删除与某个字符相邻且相同的字符 产生全排列的方法解析 一组数的全排列和组合程序实现 求一个正整数的平方根程序实现 [转]多线程队列的算法优化 [转载] STL allocator的介绍和一个基于malloc/free的allocator的简单实现 如何将一片内存链接成链表 One simple counted object pointer
类模板的模板友元函数定义
Zero Lee · 2012-06-17 · via 博客园 - Zero Lee

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