代码编译运行环境:VS2017+Debug+Win32


严格来说,函数模板(类模板)是不能作为一个类的友元的,就像类模板之间不能发生继承关系一样。只有当函数模板(或类模板)被实例化之后生成模板函数(或模板类),该函数(或类)才能作为其他的类的友元。为了叙述的方便,我们也称一个函数模板(或类模板)是一个类或类模板的友元,其实真正的含义是函数模板(或类模板)被实例化后生成的模板函数(模板类)作为类(或模板类)的友元。

1.把函数模板声明为类模板的友元

将函数模板申明为类模板的友元有三种方式。

##1.1在类模板内部将函数模板声明为友元
考察如下代码:

#include <iostream>
using namespace std;template<typename T> class A {T num;
public:A() {num=T(5.5);}template<typename T> friend void show(const A<T>&a);
};template<typename T> void show(const A<T>&a) {cout<<a.num<<endl;
}int main() {A<int> a;show<int>(a);
}

程序正确运行并输出5。

1.2 在类模板内部对显示模板参数的函数模板申明为友元

这种方法需要前置申明函数模板,考察如下程序。

#include <iostream>
using namespace std;
template<typename T>class A;
template<typename T>void show(const A<T>&a);template<typename T>class A {T num;
public:A() {num=T(5.5);}friend void show<T>(const A<T>&a);
};template<typename T> void show(const A<T>&a) {cout<<a.num<<endl;
}int main() {A<int> a;show<int>(a);
}

程序正确运行并输出5。

1.3 在类模板内部直接声明并定义友元函数

这种情况只能在模板类内部一起把函数的定义写出来,不能在外部实现,因为外部需要类型参数,而需要类型参数就是模板了。其实这种情况相当于一般的模板类的成员函数,也相当于一个函数模板。考察如下代码。

#include <iostream>
using namespace std;template<typename T>class A {T num;
public:A() {num=T(5.5);}friend void show(const A<T>&a) {cout<<a.num<<endl;}
};int main() {A<int> a;show(a);getchar();
}

程序正常编译运行并输出5。当然,将友元函数的定义改为:

template<typename T> void show(const A<T>&a)
{cout<<a.num<<endl;
}

也是完全可以的,如果将函数模板放在类模板外定义的话,和第一种方式相同。将函数模板申明为普通类的友元方式和上面相同,不再赘述。

2.把类模板声明为类模板的友元

把类模板声明为类模板的友元可以有两种方式。

2.1 在类模板内部将模板类申明为友元

这里要注意是对实例化后的模板类将其申明为类模板的友元,而不是类模板,因此实例化类模板时,类模板需要前置申明。考察如下程序。

#include <iostream>
using namespace std;template<typename T>class B; //类模板前置申明template<typename T> class A {T num;
public:A() {num=T(5.5);}friend class B<T>;
};template<typename T> class B {
public:static void show(const A<T>& a) {cout<<"a.num:"<<a.num<<endl;  }
};int main() {A<int> a;B<int>::show(a);
}

程序正常编译运行并输出:a.num:5。

2.2 在类模板内部将类模板申明为友元

这里要注意是直接将类模板申明为类模板的友元,而不是实例化后的模板咧,要与上面区别对待。这里就不需要将类模板B提前申明了,在类模板A中将B申明为:

template< class T> friend class B;

同样可以将类模板B申明为类模板A的友元。

不过,这两种方式在概念上还是有一些差异。第一种方式,类模板B的实例化依赖于类模板A的参数T。也就是说,对于一个特定的模板类A< t>来说,只有一个B的实例B< t>是它的友元类。而在第二中方式中,对于一个特定的模板类A< t>来说,B的任何实例B< u>都是它的友元类。

将类模板申明为普通类的友元方式和上面相同,不再赘述。


参考文献

[1] 怎样把函数模板声明为类模板的友元
[2] 陈刚.C++高级进阶教程[M].武汉:武汉大学出版社,2008.P218-222

C++ 将模板申明为友元相关推荐

  1. C++知识点61——typename与class、模板编程与继承、模板类和友元、类模板与static成员

    一.typename与class的异同 1.啥时候既可以使用typename,又可以使用class? 当表示模板参数的时候,二者没有区别 2.啥时候只能使用typename,不能使用class? 当模 ...

  2. 类模板,多种类型的类模板,自定义类模板,类模板的默认类型,数组的模板实现,友元和类模板,友元函数,类模板与静态变量,类模板与普通类之间互相继承,类模板作为模板参数,类嵌套,类模板嵌套,类包装器

     1.第一个最简单的类模板案例 #include "mainwindow.h" #include <QApplication> #include <QPush ...

  3. 【C++】模板类的友元函数

    模板类友元函数 模板类的友元函数 参考:https://blog.csdn.net/dreamer_lhs/article/details/53580088 区分:友元是否为函数模板 非模板友元 约束 ...

  4. 当类模板遇到了友元函数

    在我学习数据结构的时候,选用了<数据结构(用面向对象方法与C++语言描述)>殷人昆 编著 这本教材.这本书代码较老有一些错误,好多是无法直接在新版本编译器下实现的. 当时我C++模板学的不 ...

  5. C++ 模板类和友元

    模板类的友元分三类: 1,非模板友元. 2,约束模板友元,即友元的类型取决于类被实例化时的类型. 3,非约束模板友元,即友元的所有具体化都是类的每一个具体化的友元. 1,模板类的非模板友元函数 cou ...

  6. 类模板中的友元,友元类

    一:让类模板的某个实例成为友元. #include <iostream> #include <vector> #include <list> using names ...

  7. C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…

    在c++海大本科课程设计的最后章节(模板使用 )中涉及到了在Mat类模板中定义友元函数friend Mat<T> operator+(Mat<T> &m, T num) ...

  8. C++ - 类模板(class template)友元(friend) 的 全部六种形式 及 代码

    类模板(class template)友元(friend) 的 全部六种形式 及 代码 版权所有, 禁止转载, 如有需要, 请站内联系; 本文地址: http://blog.csdn.net/caro ...

  9. friend keyword 对于模板 并不只不过友元!!!

    friend是C++中封装的漏网之鱼. C++中的friend同意其它的类或者是函数訪问本类的不论什么成员.甚至是private成员,仅仅要该类声明其为友元. 但是,在有些情况下,并非同意外界訪问类的 ...

最新文章

  1. deeplearning量化
  2. 关于Activity class {package/class} does not exist
  3. ASP.NET MVC3 在WebGrid中用CheckBox选中行
  4. 高科技领域零的突破永不嫌多 --- 我看嫦娥四号成功登陆月球背面
  5. react小测试忘记一个细节不显示
  6. Boost:align对齐的测试程序
  7. php 5.3 require,PHP5.3提示PHP Wrequire(./xx.php)arning: [function.require]: failed to open stream
  8. 软件工程学习笔记《四》需求分析
  9. C++笔记:select多路复用机制
  10. 社交系统ThinkSNS-plus(TS+)V1.0发布!
  11. 支持批任务的Coscheduling/Gang scheduling
  12. 高效能程序员的七个习惯
  13. KINDEDITOR取值并写入数据库的操作
  14. 解析FL Studio冻结小技巧
  15. 英特尔核显驱动hd630_全新CPU性能天梯图,十代英特尔与R3 3100/3300X定位讲解
  16. 星星之火-51:LTE的物联网技术,Cat-M与NB-IoT的比较
  17. 个人电脑php网站搭建,如何在本地电脑搭建自己网站的流程(图文教程)
  18. Ubuntu20.10系统FreeCAD 0.19编译安装
  19. java实现表情符号过滤
  20. 网页模板设计中5种常见的设计版式类型介绍

热门文章

  1. 记录lombok的使用
  2. C++程序员Protocol Buffers基础指南
  3. gradle 构建测试
  4. SQL进阶六:字符串函数
  5. Linux下DNS服务管理
  6. 线路由器常见故障和排除方法
  7. Timus 1079. Maximum
  8. Linux 开发环境工具 下载网址大全
  9. curl error code 60 51 代码解决方式
  10. L1-080 乘法口诀数列 (20 分)-PAT 团体程序设计天梯赛 GPLT