From: Dearlove on
On 4 Oct, 22:39, Neil Butterworth <nbutterworth1...(a)gmail.com> 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.

No, look more closely, those are standard friendship grants by a class
to another class. The problem is that the first one involves an
illegal reference to a class that hasn't been defined yet. Swapping
the order doesn't help due to the mutual cross-reference. A class
forward declaration (that allows a class friendship grant) doesn't
work for a function friendship grant. My question is can I achieve
what I want, each part of which is allowed, but all together.


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

From: Paul Bibbings on
<snip>
> class Y; // #1
>
> 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();
> };

Correction: The forward declaration of class Y in #1, of course, has no
relevance to the example as given and is merely a throw back from an initial
idea that I omitted to edit out.

Regards

Paul Bibbings

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

From: Francis Glassborow on
Neil Butterworth wrote:
> 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
>

No he used the wrong term, I am not sure what the right one would be.
Mutual dependence perhaps. He clearly wants to grant X::f() access to
Y's internals and Y::g() access to X's internals. I am not sure why he
wants to do that. Perhaps if the OP explains the problem he is trying to
solve we could find a way to solve it. C++ will not let him do what he
is trying directly and the indirect solutions seem far too heavyweight.

As he owns both X and Y I cannot see what the problem is with allowing
both access to the other's private parts.

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

From: red floyd 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 might want to look into the "Attorney-Client" idiom.

http://www.ddj.com/cpp/184402053/


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

From: Dearlove on
On 5 Oct, 19:23, Paul Bibbings <paul_bibbi...(a)googlemail.com> wrote:
> (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.)

As presented, yes, what I really meant to indicate was there were some
private
data members.

Just to nitpick, f and g could be private - and long as called by
other public
functions not shown. But that's obfusticating the example which should
be

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

etc.

Thanks for that.

Your hack is indeed ugly, and I won't be using it (cure worse than
disease
and all that). But it was instructive (in particular a way of relating
classes by templates that I don't have a use for now, this case
excluded,
but maybe I will one day) which was what I was after. Thanks again.

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