第 1 类:

普通类A的 普通类B 友元(一对一友好关系):

无需前置声明class B,当class B第一次出现在friend声明中时,该名字被隐式地认为可见。

class A
{
friend class B;
public:
void f()
{ cout << "class A"; } private:
int a;
}; class B
{
public:
void f()
{ cout << "class B"; } void accessA(A& a)
{ cout << a.a; }
};

第 2 类:

普通类A的 实例化了的模板类B 友元(一对一友好关系):

如果普通类A的友元是一个实例化了的特定模板,那么这个具体实例化了的类在被声明为友元时,正如使用vector一样,要带具体的类型参数,如vector<int>,所以是friend class B<int>,但是和前面一种声明相比,编译器在读取class B<int>觉得很怪异,不知道这个<int>是什么东西,因此会报错,为了让编译器认识它,知道它是个实例化了的模板,必须在class声明之前先提前告知编译器class B原本是个模板,friend声明友元时表明了这是某一个具体模板实例。

template <typename> class B;

class A
{
friend class B<int>;
public:
void f()
{ cout << "class A"; } private:
int a;
}; template <typename T>
class B
{
public:
void f()
{ cout << "class B"; } void accessA(A& a)
{ cout << a.a; } };

第 3 类:

普通类A的 模板类B 友元(一对多友好关系):

这里普通类class A的友元是模板class B,而不是某一个具体实例化了的class B<>,只要是这个模板实例化出来的B都是A的友元。

class A
{
template <typename T> friend class B;
public:
void f()
{ cout << "class A"; } private:
int a;
}; template <typename T>
class B
{
public:
void f()
{ cout << "class B"; } void accessA(A& a)
{ cout << a.a; } };

第 4 类:

实例化模板类A的 实例化模板类B 友元(一对一友好关系):

同第2类相似,这里模板类A的友元类B也是一个模板,为了让编译器认识,必须得提前声明其是模板。且class A和class B使用相同模板类型参数,因此他们在使用相同类型实例化后得到的实例类是对应类型的一对一友好关系。

template <typename>class B;

template <typename T>
class A
{
friend class B<T>;
public:
void f()
{ cout << "class A"; } private:
T a;
}; template <typename U>
class B
{
public:
void f()
{ cout << "class B"; } void accessA(A<U>& a)
{ cout << a.a; } };

第 5 类:

模板类A的 实例化模板类B 友元(多对一友好关系):

同第2类相似,这里模板类A的友元类B也是一个模板,为了让编译器认识,必须得提前声明其是模板。B是一个特定的实例化了的模板类,它是任意模板A实例化后的友元。

template <typename> class B;

template <typename T>
class A
{
friend class B<int>;
public:
void f()
{ cout << "class A"; } private:
T a;
}; template <typename U>
class B
{
public:
void f()
{ cout << "class B"; } void accessA(A<U>& a)
{ cout << a.a; } };

第 6 类:

任意实例化模板类A的 模板类B 友元(多对多友好关系):

任意一个实例化的A对任意实例化的B都是友好关系。

template <typename T>
class A
{
template <typename X> friend class B;
public:
void f()
{ cout << "class A"; } private:
T a;
}; template <typename U>
class B
{
public:
void f()
{ cout << "class B"; } void accessA(A<U>& a)
{ cout << a.a; } };

存在模板类A的某一特定实例化对模板类B的任意实例化都是友好关系的说明吗?回答是不存在。因为实例化A时,A必然已经定义过了,对于一个定义过了的模板,再去添加模板的友元,这是个悖论。

C++11模板友元语法的更多相关文章

  1. 模板类的约束模板友元函数:template friend functions

    本来这篇博客是不打算写的,内容不是很难,对于我自己来讲,更多的是为了突出细节. 所谓template friend functions,就是使友元函数本身成为模板.基本步骤:1,在类定义的前面声明每个 ...

  2. [转载]ECMall模板解析语法与机制

    ECMall模板解析语法与机制 2011-05-22 在ECMall模板中,用"{"开头,以"}"结尾就构成一个标签单元,"{"紧接着的单词 ...

  3. YAML 模板文件语法

    YAML 模板文件语法 默认的模板文件是 docker-compose.yml,其中定义的每个服务都必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile)来自动构建. 其 ...

  4. [转]Markdown 11种基本语法

    Markdown 11种基本语法 现在是我在学习Markdown时做的笔记.学完这些Markdown的基本使用已经不成问题. 1. 标题设置(让字体变大,和word的标题意思一样) 在Markdown ...

  5. ThinkPHP第五天(提交类型判定常量IS_POST等,错误页面种类,Model实例化方式,模板中使用函数,foreach循环,模板中.语法配置)

    1.IS_GET.IS_POST.IS_PUT.IS_DELETE.IS_AJAX常量,方便快捷实现各个判断. 在Action类中还可以使用$this->isPost()等进行判断. 2.错误页 ...

  6. Markdown 11 种基础语法

    现在是我在学习Markdown时做的笔记.学完这些Markdown的基本使用已经不成问题. 1. 标题设置(让字体变大,和word的标题意思一样)在Markdown当中设置标题,有两种方式: 第一种: ...

  7. discuz模板引擎语法

    论坛的首页模板:forum/discuz.htm 版块的内容模板:forum/forumdisplay.htm 主题的查看模板:forum/viewthread.htm 帖子的内容模板:forum/p ...

  8. c++11 模板的别名

    c++11 模板的别名 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #inclu ...

  9. C++:模板友元

    模板友元函数在类内声明类外定义时都必须加模板前缀,另外模板要写在一个文件内 // generates undefined error for the operator<< function ...

随机推荐

  1. [转载]使用VS2015搭建Lua开发环境

    参考原文请看: Lua学习笔记1:Windows7下使用VS2015搭建Lua开发环境(一) Lua学习笔记2:Windows7下使用VS2015搭建Lua开发环境(二) 本篇主要分以下几个部分: 一 ...

  2. BZOJ1022[SHOI2008]小约翰的游戏——anti-SG(反尼姆博弈)

    题目描述 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有n堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到 ...

  3. SVM学习笔记-线性支撑向量机

    对于PLA算法来说,最终得到哪一条线是不一定的,取决于算法scan数据的过程. 从VC bound的角度来说,上述三条线的复杂度是一样的 Eout(w)≤Ein0+Ω(H)dvc= ...

  4. 06 自学Aruba之win7系统802.1x认证网卡设置指导

    点击返回:自学Aruba之路 06 自学Aruba之win7系统802.1x认证网卡设置指导 步骤1.在桌面任务栏找到“打开网络和共享中心”,点击进入: 步骤2.点击“管理无线网络”,进入无线网络配置 ...

  5. 自学Zabbix3.10.2.1 linux如何配置使用sendEmail发送邮件

    点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix3.10.2.1 linux如何配置使用sendEmail发送邮件 sendEma ...

  6. 【BZOJ2229】[ZJOI2011]最小割(网络流,最小割树)

    [BZOJ2229][ZJOI2011]最小割(网络流,最小割树) 题面 BZOJ 洛谷 题解 戳这里 那么实现过程就是任选两点跑最小割更新答案,然后把点集划分为和\(S\)联通以及与\(T\)联通. ...

  7. 如何安装/卸载workflow manager 1.0

    安装 1. 配置文件: <Workflow> <!--http://msdn.microsoft.com/en-us/library/windowsazure/jj193269(v= ...

  8. centos6.5安装jdk(解压tar.gz)

    0.说明 下载jdk文件包jdk-7u79-linux-x64.tar.gz. 1.环境清理(系统自带的OpenJDK) 1.1 查看OpenJDK的安装包 $ rpm -qa |grep java ...

  9. [动态dp]线段树维护转移矩阵

    背景:czy上课讲了新知识,从未见到过,总结一下. 所谓动态dp,是在动态规划的基础上,需要维护一些修改操作的算法. 这类题目分为如下三个步骤:(都是对于常系数齐次递推问题) 1先不考虑修改,不考虑区 ...

  10. centos7配置本地yum源 使用安装镜像安装软件

    1. 在cdrom挂载安装镜像.(物理机则插入光盘,虚拟机则在CD/DVD中选择iso镜像.如果虚拟机mount时提示找不到则在选择iso镜像上方勾选“已连接”和“启动时连接”,或者点击 虚拟机下方状 ...