第 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. ceph PG数量调整/PG的状态说明

    优化: PG Number PG和PGP数量一定要根据OSD的数量进行调整,计算公式如下,但是最后算出的结果一定要接近或者等于一个2的指数.调整PGP不会引起PG内的对象的分裂,但是会引起PG的分布的 ...

  2. 2.9 C++使用默认参数的构造函数

    总结: 默认参数的构造函数,其默认参数必须置于参数列表的结尾. 设计类的构造函数的时候最好不要同时是用构造函数的重载和带参数的构造函数. 我们可以想象一个这样的场景:某一天书店整理库存,发现了一些非常 ...

  3. 自学Python2.9-循环(while、for)

    自学Python之路 自学Python2.9-循环(while.for) 1. while循环 Python中while语句的一般形式: while 判断条件: 语句 作用:提高开发效率,提高代码重用 ...

  4. [2019/03/17#杭师大ACM]赛后总结(被吊锤记)

    前言 和扬子曰大佬和慕容宝宝大佬一组,我压力巨大,而且掌机,累死我了,敲了一个下午的代码,他们两个人因为比我巨就欺负我QwQ. 依旧被二中学军爆锤,我真的好菜,慕容宝宝或者是扬子曰大佬来掌机一定成绩比 ...

  5. 批量修改sharepoint 2013站点里区域设置

    cls [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") foreach ($we ...

  6. 洛谷 P4097 [HEOI2013]Segment 解题报告

    P4097 [HEOI2013]Segment 题目描述 要求在平面直角坐标系下维护两个操作: 在平面上加入一条线段.记第 \(i\) 条被插入的线段的标号为 \(i\) 给定一个数 \(k\),询问 ...

  7. 前端学习 -- Html&Css -- 背景

    background 在一个声明中设置所有的背景属性. background-attachment 设置背景图像是否固定或者随着页面的其余部分滚动. background-color 设置元素的背景颜 ...

  8. 在Android中afinal框架下實現sqlite數據庫版本升級的辦法

    public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int new Version) 這個方法在實現時需要重寫.   pub ...

  9. 转载:Windows下stdlib.h与glut.h中exit()函数重复定义的解决方案

    最近用到 OpenGL的第三方库Glut,碰到了exit()这个函数在stdlib.h与glut.h两个头文件中重复定义的情况,解决方案如下: 打开glut.h,找到exit()函数定义的地方(144 ...

  10. Java:判断当前操作系统界面采用的主题是windows经典样式还是xp样式

    想起两三年前,发现写Java界面的时候,如果将当前界面的layout设为null,由于windows的不同主题界面下,标题栏的高度不一致,导致当前界面表现也不一致. 当时就想找到一个办法先判断当前用户 ...