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

推荐订阅源

Cyberwarzone
Cyberwarzone
V
Vulnerabilities – Threatpost
T
Tenable Blog
Forbes - Security
Forbes - Security
Simon Willison's Weblog
Simon Willison's Weblog
AWS News Blog
AWS News Blog
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
Project Zero
Project Zero
C
CXSECURITY Database RSS Feed - CXSecurity.com
V
Visual Studio Blog
WordPress大学
WordPress大学
Latest news
Latest news
K
Kaspersky official blog
T
Tailwind CSS Blog
T
Threat Research - Cisco Blogs
B
Blog RSS Feed
C
Cisco Blogs
博客园 - 聂微东
Martin Fowler
Martin Fowler
T
The Blog of Author Tim Ferriss
小众软件
小众软件
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
L
LINUX DO - 热门话题
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Privacy International News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
C
CERT Recently Published Vulnerability Notes
Cisco Talos Blog
Cisco Talos Blog
S
SegmentFault 最新的问题
Security Latest
Security Latest
Y
Y Combinator Blog
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
P
Privacy & Cybersecurity Law Blog
L
LINUX DO - 最新话题
月光博客
月光博客
The GitHub Blog
The GitHub Blog
博客园 - 三生石上(FineUI控件)
S
Security Affairs
P
Proofpoint News Feed
D
DataBreaches.Net
有赞技术团队
有赞技术团队
云风的 BLOG
云风的 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) 友元模板函数的模板参数类型,并不一定要求是类模板的参数类型,也可以另外声明。