在类模板中可以出现三种友元声明:
(1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数。
(2)类模板或函数模板的友元声明,授予对友元所有实例的访问权。
(3)只授予对类模板或函数模板的特定实例的访问权的友元声明。

(1)普通友元:

template<class T>

class A{

friend void fun();

//...

};
此例中fun可访问A任意类实例中的私有和保护成员

(2)一般模板友元关系

template<class type>

class A{

template<classT>

friend void fun(T u);

//...

};

这时友元使用与类不同的模板形参,T可以是任意合法标志符,友元函数可以访问A类的任何类实例的数据,即不论A的形参是int,double或其他都可以。

(3)特定的模板友元关系

template <class T> void fun(T,u);//对与特定的模板友元关系,这里的声明是必须的

template<class T>

class A{

friend voidfun<T>(T u);//这里也可以是friend void fun<char>(char u);

//...

};

此时fun只有访问类中特定实例的数据。换句话说,此时具有相同模板实参的fun函数与A类才是友元关系。即假如调用fun时其模板实参为int,则它只具有A<int>的访问权限。当然friendvoid fun<T>(Tu);中<>中的T可以是任意类型,比如int,double等

对类建立友元函数很容易。但是迁移到模板上却容易出现让人摸不着头脑的连接错误。
层次不够,不做分析,单纯介绍两种为类模板定义友元函数的方法

  1 封闭型

template< typename T >
class MyClass
{
    friend void function( MyClass< T > &arg )
    {
        
     }
 };  要点:友元函数定义在模板体内。

2 开放型
template< typename T >
class MyClass
{
    template< typename C >
    friend void function( MyClass< C > &arg );
 };

template< typename C >
void function( MyClass< C > &arg )
{
    
 }  要点:模板体内要另建模板。 
  
  3 告诉编译器声明的设个是模板
#include <iostream>
using namespace std;

template < typename T >
class A
{
    friend ostream &operator<< < T >( ostream &, const A< T > & );
 };

template < typename T >
ostream &operator<< ( ostream &output, const A< T > &a )
{
    output << "重载成功" << endl;
    return output;
 }

int main()
{
    A< int > a;
    cout << a;
 }要点:显示地在重载的运算符或者函数后面加上模板声明< T>,告诉编译器友元函数是一个类型一致的模板。

建议:
            如果希望使用函数与模板特化的类型相对应,则使用方法3(模板显示声明)
            如果希望使用函数与模板特化的类型相独立,则使用方法2(二重模板)
            简短的内联函数使用方法1

参考  http://blog.sina.com.cn/s/blog_7c2c21230100svc3.html

C++中模板类使用友元模板函数的更多相关文章

  1. c/c++ 模板与STL小例子系列&lt;二&gt; 模板类与友元函数

    c/c++ 模板与STL小例子系列 模板类与友元函数 比如某个类是个模板类D,有个需求是需要重载D的operator<<函数,这时就需要用到友元. 实现这样的友元需要3个必要步骤 1,在模 ...

  2. C++模板编程中只特化模板类的一个成员函数

    模板编程中如果要特化或偏特化(局部特化)一个类模板,需要特化该类模板的所有成员函数.类模板中大多数成员函数的功能可能是一模一样的,特化时我们可能只需要重新实现1.2个成员函数即可.在这种情况下,如果全 ...

  3. C++友元(友元函数、友元类和友元成员函数)

    友元(友元函数.友元类和友元成员函数) C++ 有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例如被重载的操作符,如输入或输出操作符,经常需要访问类的私 ...

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

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

  5. C++模板类内友元(友元函数,友元类)声明的三种情况

    根据<C++ Primer>第三版16.4节的叙述,C++类模板友元分为以下几种情况 1.非模板友元类或友元函数. 书上给了一个例子: class Foo{     void bar(); ...

  6. 友元(友元函数、友元类和友元成员函数) C++

    有些情况下,允许特定的非成员函数访问一个类的私有成员,同时仍阻止一般的访问,这是很方便做到的.例如被重载的操作符,如输入或输出操作符,经常需要访问类的私有数据成员. 友元(frend)机制允许一个类将 ...

  7. 【转】doxygen+graphviz生成工程中的类继承树及函数调用图

    转自----hequn8128 在阅读代码量比较多的项目时,类的继承树和函数调用图能够直观地向我们显示类之间或者函数之间的各种关系,方便我们了解程序的整体框架,很多时候可以起到事半功倍的作用.这里尝试 ...

  8. C++模板的实现(模板函数和模板类,附带模板实现顺序表和链表代码)

    文章链接:https://blog.csdn.net/qq_38646470/article/details/80209469

  9. Java中Collections类的排序sort函数两种用法

    java中的Colletions类主要实现列表List的排序功能.根据函数参数的传递,具体的排序可以分为 : 1.  自然排序(natural ordering). 函数原型:sort(List< ...

随机推荐

  1. 关于iframe

    iframe一般用来嵌套其他页面来使用 1.如何使用? <iframe id="iframe1" src="2.html" frameborder=&qu ...

  2. XP退役了,如何把Win7变成XP风格?| 怎么样去掉Win7的所有华丽效果? | 怎么样让Win7达到电脑最佳性能?

    XP系统退役了,以后微软停止XP系统的更新维护了. 不得不升级使用Windows7系统,但是大部分使用Windows7不习惯. 那是因为你的操作习惯,还保持在XP风格基础上. 那么有没有什么办法让Wi ...

  3. string strSQL = &quot;Select * From Employees;Select * from Customers&quot;;执行两次查询

    SqlCommand对象的字符串SQL命令可以做多个,以查询为例,用到SqlDataReader的一些方法,如ExecuteReader(),Read()(一条命令内的移动至下一记录),NextRes ...

  4. Symfony2学习笔记之表单

    对于一个Web开发者来说,处理HTML表单是一个最为普通又具挑战的任务.Symfony2集成了一个Form组件,让处理表单变的容易起来.在这一节里,我们将从基础开始创建一个复杂的表单,学习表单类库中最 ...

  5. as3+java+mysql(mybatis) 数据自动工具(四)

    现在介绍一下只配置 as3 与 java 公用的数据类,这种配置一般是该数据类只需要在 as3 与 java 之间转换,跟数据库没有关系.比如在客户端与服务端的数据交换中,需要定义一个统一返回请求的数 ...

  6. SE 2014年4月17日

    描述BGP路由属性 MED.首选值 的特点 MED相当于IGP协议中的度量值,在其他条件相同时,当本自治系统有多条到达外部自治系统的链路时,MED值小的路由优选.MED属性只能在两个自治系统间传递. ...

  7. Unity3D获取资源的方法整理:

    在使用Unity3D做项目时,获取资源的方法大致分为两种.一种是通过写代码的方式,在程序运行时,自动获取资源:一种是通过手动拖拽的方式进行获取.不管是什么类型的资源都能通过这两种方式获得,下面拿图片资 ...

  8. Flask信号和wtforms

    一.信号 1.1.所有内置信号 request_started = _signals.signal('request-started') # 请求到来前执行 request_finished = _s ...

  9. 预热一下吧《实现Redis消息队列》

    应用场景 为什么要用redis?二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成ja ...

  10. python获取文件夹的大小(即取出所有文件计算大小)

    import os path = r'/Users/authurchen/PycharmProjects/Demo' # print(os.listdir(path)) ls = os.listdir ...