首页 > 技术文章 > C++11模板友元语法

pluse 2018-07-11 15:55 原文

 

第 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必然已经定义过了,对于一个定义过了的模板,再去添加模板的友元,这是个悖论。

推荐阅读