第 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. BZOJ3653谈笑风生——可持久化线段树+dfs序

    题目描述 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称“a比b不知道 高明到哪里去了”. ? 设a 和 b 为 T 中的两个不同节点.如果 a ...

  2. 微信access_token请求之简单缓存方法封装

    还有东西要搞,就直接上代码 function.php <?php // 一个好玩的 curl 类 // https://github.com/metowolf/Meting/blob/maste ...

  3. 最小费用最大流spfa

    #include <iostream> #include <cstring> #include <cstdio> #include <queue> #d ...

  4. CUBA如何新增ServiceBean

    简单的方法 在页面MIDDLEWARE模块,可以直接新建.编辑.删除 复杂的方法 在代码中手动实现,则需要1.添加Serviceweb-spring.xml中,添加 <entry key=&qu ...

  5. 【转】 cJSON 源码解析

    关于cjson的介绍和使用方法就不在这里介绍了,详情请查看上一篇博客cjson使用方法. JSON的内存结构像广义表,可以认为是有层次的双向链表. cJSON程序中的细节点如下: 大量宏替换 大量静态 ...

  6. 使用nagios监控ssl证书过期时间

    1.编写监控脚本. # vim check_ssl_expiry.sh #!/bin/bash STATE_OK=0 STATE_WARNING=1 STATE_CRITICAL=2 Host=$1 ...

  7. 【洛谷P1858】多人背包

    题目大意:求解 0-1 背包前 K 优解的和. 题解:首先,可知对于状态 \(dp[j]\) 来说,能够转移到该状态的只有 \(dp[j],dp[j-w[i]]\).对于 K 优解来说,只需对状态额外 ...

  8. vi怎么查找关键字

    进入vi的命令模式,具体操作:编辑模式下键入“:”,此时进入命令模式 在命令模式下键入“/”.

  9. [持续更新] 文章列表 Last Update: 8/21/2017

    1.前端 HTML5快速学习二 Canvas@20141125 HTML5快速学习一@20141122 2.ASP.NET(MVC) MVC5+EF6 完整教程17--升级到EFCore2.0@201 ...

  10. xkcd 单线程下载图片

    Python爬虫视频教程零基础小白到scrapy爬虫高手-轻松入门 https://item.taobao.com/item.htm?spm=a1z38n.10677092.0.0.482434a6E ...