From: Dearlove on
Can I. and if so how, achieve

class X
{
private:
void f();
friend void Y::g();
};

class Y
{
private:
void g();
friend void X::f();
};

Obviously I can forward declare class Y before X, but that's not
sufficient.

The obvious workaround is class friendship. And a design that doesn't
need the above is also a solution. But if for some reason I want the
above, what's the closest I can get?


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Neil Butterworth on
Dearlove wrote:
> Can I. and if so how, achieve
>
> class X
> {
> private:
> void f();
> friend void Y::g();
> };
>
> class Y
> {
> private:
> void g();
> friend void X::f();
> };
>
> Obviously I can forward declare class Y before X, but that's not
> sufficient.
>
> The obvious workaround is class friendship. And a design that doesn't
> need the above is also a solution. But if for some reason I want the
> above, what's the closest I can get?

You appear to be asking how a class can grant itself friendship to
another class. The answer is, there is no way of doing that, as it would
completely negate the whole point of having private members.

Neil Butterworth



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Neil Butterworth on
Neil Butterworth wrote:
> Dearlove wrote:
>> Can I. and if so how, achieve
>>
>> class X
>> {
>> private:
>> void f();
>> friend void Y::g();
>> };
>>
>> class Y
>> {
>> private:
>> void g();
>> friend void X::f();
>> };
>>
>> Obviously I can forward declare class Y before X, but that's not
>> sufficient.
>>
>> The obvious workaround is class friendship. And a design that doesn't
>> need the above is also a solution. But if for some reason I want the
>> above, what's the closest I can get?
>
> You appear to be asking how a class can grant itself friendship to
> another class. The answer is, there is no way of doing that, as it would
> completely negate the whole point of having private members.


Actually, I just re-read the question and maybe you are not asking that.
But I'm not sure. When you say:

class Y
{
private:
void g();
friend void X::f();
};

Are you trying to say that any member of Y should be able to call X::f()
or that X::f() should be able to call any member of Y? Whichever, the
call would not be recursive, per your questions title.

Neil Butterworth

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Paul Bibbings on
Neil Butterworth wrote:
> Dearlove wrote:
>> Can I. and if so how, achieve
>>
>> class X
>> {
>> private:
>> void f();
>> friend void Y::g();
>> };
>>
>> class Y
>> {
>> private:
>> void g();
>> friend void X::f();
>> };
>
> You appear to be asking how a class can grant itself friendship to
> another class. The answer is, there is no way of doing that, as it would
> completely negate the whole point of having private members.
>
> Neil Butterworth
>

I'm not sure that I follow you response here. To my understanding, the OP is
merely wanting to take the valid construct:

class X {
// ...
public:
void f() { }
};

class Y {
// ...
public:
void g() { }
friend void X::f();
};

and add a reciprocation so that void Y::g() is likewise a friend of X. (Notice,
however, that in the above I have added the correction of making X::f() and
Y::g() public, otherwise they would not be visible at the points where it is
intended the friendship be granted.)

For myself, I can't immediately think how this could be easily achieved. It is
certainly worth more thought than I have yet given it, so off the top of my head
I can only come up with the following ugly hack:

class Y;

template<typename T>
class X_t {
int iX_;
public:
void f();

friend void T::g();
};

class Y {
int iY_;
public:
void g();

template<typename T>
friend void X_t<T>::f();
};


typedef X_t<Y> X;

template<>
void X::f() { Y().iY_ = 0; }

void Y::g() { X().iX_ = 0; }

int main()
{
X x; x.f();
Y y; y.g();
}

Regards
Paul Bibbings

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: shahav on

> You appear to be asking how a class can grant itself friendship to
> another class. The answer is, there is no way of doing that, as it would
> completely negate the whole point of having private members.
>
> Neil Butterworth
>

I don't think you are rephrasing it correct.
Mainly when "big" classes are involved better control can be achieved
by reducing friendship to specific methods and not complete class.

I did run into above problem and the bypass i used is granting
friendship to the whole class in one direction.

A different approach i used to reduce dependency:
is having a global method instead of Y::g
void Y__g(x* this_);
I don't like either, but i think this would as "close" as possible...
Rabin

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]