使用模板将成员函数集声明为好友 [英] Declaring set of member functions as friend by using template

查看:100
本文介绍了使用模板将成员函数集声明为好友的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码:

class A;

struct B {
    static void doIt(A* pa);
};

struct C {
    static void doIt(A* pa);
};

class A {
    int i = 9;
    // below works but requires a line per each type
    friend void B::doIt(A* pa);
    friend void C::doIt(A* pa);

    // the below however doesn't work
    // template<typename T>
    // friend void T::doIt(A* pa);
      // (gcc error: member 'void T::doIt(A*)' declared as friend before type 'T' defined)
      // (clang just ignores the above and the error is on accessing A::i in B and C)    
};

void B::doIt(A* pa) {
    cout << pa->i << endl;
}

void C::doIt(A* pa) {
    cout << pa->i *2 << endl;
}

int main() {
    A a;
    B::doIt(&a);
    C::doIt(&a);
}

是否可以替换多个friend声明以允许所有void T::doIt(A* pa)方法访问A的私有成员?

Is it possible to replace the multiple friend declarations to allow all void T::doIt(A* pa) methods access the private members of A?

尝试实例化A上方的BC并没有帮助.

Trying to instantiate B and C above A doesn't help.

推荐答案

我相信可以使用CRTP和私有/受保护的虚拟继承来完成与您期望的操作类似的操作.下面的代码仅是演示,绝对需要一些工作,例如不涉及模板方法的友谊:

I believe something similar to what you desire can be done using CRTP and private/protected virtual inheritance. The code below is only demonstration and definitely needs some work e.g. to not to involve template method friendship:

#include <iostream>

using namespace std;

class base {
protected:
    int i = 9;
};

template <class F>
class crtp_base: virtual base { // private inheritance!
    template <class T>
    friend void F::doIt(T*);
};

template <class... AllF>
struct crtp_bases: crtp_base<AllF>... { };

struct B {
    template <class T>
    static void doIt(T* pa);
};

struct C {
    template <class T>
    static void doIt(T* pa);
};

class A: public crtp_bases<B, C> {
};

template <class T>
void B::doIt(T* pa) {
    cout << pa->i << endl;
}

template <class T>
void C::doIt(T* pa) {
    cout << pa->i * 2 << endl;
}

int main() {
    A a;
    B::doIt(&a);
    //cout << a.i << endl; // error i is private member of 'base'
}

[实时演示]

这篇关于使用模板将成员函数集声明为好友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆