给出以下代码:
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
的私有成员?
尝试实例化B
以及C
以上的A
并没有帮助。
答案 0 :(得分:1)
不完全是你问的是什么,但......如果你对B
,C
等结构进行模板化,你可以得到类似的东西。
#include <iostream>
class A;
template <std::size_t>
struct X
{ static void doIt(A* pa); };
class A
{
int i = 9;
template <std::size_t I>
friend void X<I>::doIt (A* pa);
};
template <>
void X<0U>::doIt(A* pa)
{ std::cout << pa->i << std::endl; }
template <>
void X<1U>::doIt(A* pa)
{ std::cout << pa->i * 2 << std::endl; }
template <>
void X<2U>::doIt(A* pa)
{ std::cout << pa->i * 3 << std::endl; }
using B = X<0U>;
using C = X<1U>;
using D = X<2U>;
int main() {
A a;
B::doIt(&a);
C::doIt(&a);
D::doIt(&a);
}
答案 1 :(得分:1)
我相信使用CRTP和私有/受保护的虚拟继承可以完成类似于您的需求。下面的代码只是演示,肯定需要一些工作,例如不涉及模板方法友谊:
#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'
}
答案 2 :(得分:0)
我看不到直接的方法,但是一个解决方法可能是使用几个静态方法声明一个类(而不是使用一个静态方法的几个类),然后将此类声明为朋友,如:
...
struct D {
static void doItB(A* pa);
static void doItC(A* pa);
};
class A {
...
friend struct D;
...
};
void D::doItB(A* pa) {
cout << pa->i << endl;
}
...
D::doItB(&a);
D::doItC(&a);
...