模板类的约束模板友元函数:template friend functions
本来这篇博客是不打算写的,内容不是很难,对于我自己来讲,更多的是为了突出细节。
- 所谓template friend functions,就是使友元函数本身成为模板。基本步骤:
1,在类定义的前面声明每个模板函数。eg:template <typename T> void counts(); template <typename T> void report<>(T &);
2,在类声明中再次将模板声明为友元。template <typename TT>
class HasFriendT
{
....
friend void counts<TT>();
friend void report<>(Testclass<TT> &)
};声明中<>指出这是模板具体化,注意模板具体化和函数具体化有点不一样。对于report,<>可以为空,因为可以从函数参数推断出模板类型参数。在声明的例子中是:HasfriendT<TT>。然而,也可以使用report<HasFriendT<TT>> 来代替 report<> 。
但是counts没有参数,因此必须使用模板参数语法(<TT>)来指明其具体化。还要注意的是,TT是Testclass类的参数类型。
3,为友元提供模板定义。这里的定义只是就“泛型”TT,每个函数定义一个就行。并不需要像函数显式具体化那样为每个特定的类型通通都定义。 - 好了,接下来看代码:
#include <iostream> using std::cout;
using std::endl; template <typename T> void counts();
template <typename T> void report(T &); template <typename TT>
class HasFriendT
{
private:
TT item;
static int ct;
public:
HasFriendT(const TT & i) : item(i) { ct++; }
~HasFriendT() { ct--; }
friend void counts<TT>();
friend void report<HasFriendT<TT>>(HasFriendT<TT> &);
//note: use report<HasFriendT<TT>> not report<TT>
}; template <typename T>
int HasFriendT<T>::ct = ; template <typename T>
void counts()
{
cout << "template size: " << sizeof(HasFriendT<T>) << "; ";
cout << "template counts(): " << HasFriendT<T>::ct << endl;
} template <typename T>
void report(T & hf)
{
cout << hf.item << endl;
} int main(void)
{
counts<int>();
HasFriendT<int> hfi1();
HasFriendT<int> hfi2();
HasFriendT<double> hfi3(15.5); report(hfi1);
report(hfi2);
report(hfi3); cout << "counts<int>() output: \n";
counts<int>();
cout << "counts<double>() output: \n";
counts<double>(); return ;
}开始的时侯,在声明模板时明明counts 和 report 的<>内都是typename T(即<typename T>),我想不明白为什么在class中friend void counts<TT>() 和 friend void report<HasFriendT<TT>>(HasFriendT<TT> &) <>内的参数就不一样了呢(一个是<HasfriendT<TT>> 一个 是 <TT>)。后来仔细看了下,才发现report函数和counts函数处理的对象不一样。report处理的是item,它是类HasFrriendT的成员数据,所以它的类型是<HasFriendT<TT>>。而counts处理的是一个静态成员,对于静态类成员,可以在类声明之外使用单独的语句进行初始化,这是因为静态类是单独存储的,而不是对象的组成部分。也正如本文开头所指出那样:在countsde<>中, TT是Testclass类的参数类型。
- 不知到你有没有发现上面的声明中,一会用TT,一会用T。开始我也纳闷,神经兮兮的认为它们的不同是不是隐含什么细节。后来将它们全部改成TT再编译,发现没什么问题。原来这只是一个泛型的符号而已。。当然,它们也可能真的存在什么不同,但现在我还没有发现。
模板类的约束模板友元函数:template friend functions的更多相关文章
- c++面向对象 之 基础 类修饰符 构造函数 友元函数
1,类和对象 定义一个类,本质上是定义一个数据类型的蓝图.这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作. 类定义格式 ...
- C++模板的实现(模板函数和模板类,附带模板实现顺序表和链表代码)
文章链接:https://blog.csdn.net/qq_38646470/article/details/80209469
- C++模板类中友元函数的写法
首先,已声明好的类Triangle file://Triangle.h template<class T> class Triangle{ public: Triangle(T width ...
- C++学习之友元类和友元函数
C++学习之友元类和友元函数 模板类声明也可以有友元,模板的友元可以分为以下几类: 1.非模板友元: 2.约束模板友元,即就是友元的类型取决于类被实例化的时候的 ...
- 类模板语法知识体系梳理(包含大量常犯错误demo,尤其滥用友元函数的错误)
demo 1 #include <iostream> #include <cstdio> using namespace std; //template <typenam ...
- c/c++ 模板与STL小例子系列<二> 模板类与友元函数
c/c++ 模板与STL小例子系列 模板类与友元函数 比如某个类是个模板类D,有个需求是需要重载D的operator<<函数,这时就需要用到友元. 实现这样的友元需要3个必要步骤 1,在模 ...
- c++类模板之友元函数
前言:自从开始学模板了后,小编在练习的过程中.常常一编译之后出现几十个错误,而且还是那种看都看不懂那种(此刻只想一句MMP).于是写了便写了类模板友元函数的用法这篇博客.来记录一下自己的学习. 普通友 ...
- C++ 模板函数与模板类
一.模板函数 函数模板提供了一类函数的抽象,即代表了一类函数.当函数模板被实例化后,它会生成具体的模板函数.例如下面便是一个函数模板:
- C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)
转自:https://www.cnblogs.com/zhoug2020/p/6581477.html 模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多 ...
随机推荐
- 【Android】XML文件的解析
1.首先我们可以在res包路径下创建一个raw包,然后在raw下创建一个email.xml 文件,并修改其内容如下: <?xml version="1.0" encoding ...
- c中的可重入和不可重入函数
可重入和不可重入 的基本概念 ---简介--- 可重入函数主要用于多任务环境中,一个可重入的函数简单来说就是可以被中断的函数,也就是说,可以在这个函数执行的任何时刻中断它,转入OS调度下去执行另外一段 ...
- 删除 vim 命令
x 删除当前光标下的字符dw 删除光标之后的单词剩余部分.d$ 删除光标之后的该行剩余部分.dd 删除当前行. c 功能和d相同,区别在于完成删除操作后进入INSERT MODEcc 也是删除当前行, ...
- 在mysql 5.6的环境下修改生产环境的表结构(在线ddl) ----工具pt-osc
随着需求的变化越来越快,在线修改表结构变得越来越需要. 在mysql5.6以前,mysql的修改表结构操作会锁表,这样就会造成开发人员或者DBA修改表结构必须要等到凌晨流量谷值或者停服修改.这样必定会 ...
- 五子棋AI大战OC实现
Gobang 五子棋AI大战,该项目主要用到MVC框架,用算法搭建AI实现进攻或防守 一.项目介绍 1.地址: github地址:Gobang 2.效果图: 二.思路介绍 大概说下思路,具体看代码实现 ...
- storage在IE8下的兼容性写法
storage 本地缓存,这是HTML5的一个非常好用的地方,具体好用在哪,网上可以找到很多,但是我觉得总结的都不是很完整,我建议大家有空的话可以看下JavaScript权威指南这本书,里面对于这个方 ...
- jdk源码剖析五:JDK8-废弃永久代(PermGen)迎来元空间(Metaspace)
目录 1.背景 2.为什么废弃永久代(PermGen) 3.深入理解元空间(Metaspace) 4.总结 ========正文分割线===== 一.背景 1.1 永久代(PermGen)在哪里? 根 ...
- CentOS_5.6下使用cmake编译MySQL_5.5.11教程
注:资料来自网络 Centos 5.6编译安装mysql 5.5.11 2011年06月24日 星期五 05:33 MySQL 最新的版本5.5.11需要cmake编译安装,估计以后的版本也会采 ...
- 【WPF】学习笔记(二)——依旧是一个电子签名板
这篇博客呢,主要谈谈在实现电子签名功能中踩过的几个坑:1.System.BadImageFormatException异常:2.无法加载DLL“###.dll”,: 找不到指定的模块. (异常来自 H ...
- 如何解决 chrome 58 版本更新导致的 fiddler https 抓包不可用问题
注意!如果该方法不生效,请先卸载原有 fiddler 后再进行新版本 fiddler 安装步骤即可. chrome 于(上周?上上周?)推送了chrome 58 版本的更新,这次更新中直接去掉了证书未 ...