Topic: Transitive friend declarations


Author: Christian K <christiankaeser87@googlemail.com>
Date: Tue, 14 May 2013 05:36:43 -0700 (PDT)
Raw View
------=_Part_2768_31402384.1368535003868
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Incidentally I am currently thinking about a kind of extended friend=20
declaration differing from the one DeadMG just proposed here in Even more=
=20
extended friend declarations<https://groups.google.com/a/isocpp.org/forum/?=
fromgroups#!topic/std-proposals/-iAx92dSN9M>
..

Right now I am studying approaches to reflection in C++. N3326<http://www.o=
pen-std.org/jtc1/sc22/wg21/docs/papers/2012/n3326.pdf>(Sequential access to=
 data members) by Andrzej Krzemie=C5=84ski seems=20
particularly promising to me at the moment, as that paper is not too broad=
=20
in scope, quite concrete in its wording and should be therefore relatively=
=20
easy to implement. That is something I plan to do experimentally in Clang.

One aspect of the paper is the handling of access control for the exposed=
=20
reflected-member tuple. It suggests that in the case that S contains=20
private fields, the MEMBERS_T<S> class only allow access to the=20
members-of-S tuple to S and friends of S. For this the author proposes to=
=20
add all the friend declarations in S to MEMBERS_T<S> in some way, maybe=20
through compiler magic.

This lead me to think about a (as generally useful as possible) way this=20
could be archived. As is stated in the standard ([class.friend]p10), a=20
friend declaration has no transitive effect.

I propose adding a new friend declaration directive, something like "friend=
=20
*import* <class-type>", that differs in this regard and has the effect of=
=20
adding ("importing") all the friend declarations in <class-type> into the=
=20
current (class) context.

As "*import*" is no standard C++ keyword, I personally favor using "*using*=
"=20
instead, with "*inline*" also a possibility.

For a motivating example see N3326, which I think can be represented by=20
something like this:

class A {
int private_m;
friend void some_free_function();
};

template<class T>=20
class MEMBER_T {
// for A: std::tuple<int&>
typedef std::tuple<...> all_members_tuple;

// equivalent to "friend T" and all of T's friend declarations
friend *using* T;

// similar to std::tie(t_inst.private_m) in this case
// note that this function is private to guard against unrestricted
// access to private members of T
static all_members_tuple members(T& t_inst);
};

void some_free_function()=20
{
A a_inst;
auto a_as_tuple =3D MEMBER_T<A>::members(a_inst); // Okay!
get<0>(a_as_tuple) =3D 42;=20
assert(a_inst.private_m =3D=3D 42);
}

In practice this should be most useful for serialization functions that are=
=20
privileged through "friend" by a class to serialize them. Then these=20
serialization functions can also use a MEMBER_T-like reflection facility to=
=20
get access to the private members, without MEMBER_T mentioning them=20
explicitly or just providing purely unrestricted access as is done in=20
languages like C# and Java(?).

I would be very interested in feedback to this idea. Are there great=20
concerns against a transitive friend declaration in general? Is this=20
motivating example enough to warrant inclusion of something like this into=
=20
the standard?

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/?hl=3Den.



------=_Part_2768_31402384.1368535003868
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Incidentally I am currently thinking about a kind of extended friend declar=
ation differing from the one DeadMG just proposed here in <a href=3D"https:=
//groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-proposals/-iA=
x92dSN9M">Even more extended friend declarations</a>.<div><br></div><div>Ri=
ght now I am studying approaches to reflection in C++. <a href=3D"http://ww=
w.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3326.pdf">N3326</a> (Sequen=
tial access to data members) by Andrzej Krzemie=C5=84ski seems particularly=
 promising to me at the moment, as that paper is not too broad in scope, qu=
ite concrete in its wording and should be therefore relatively easy to impl=
ement. That is something I plan to do experimentally in Clang.</div><div><b=
r></div><div>One aspect of the paper is the handling of access control for =
the exposed reflected-member tuple. It suggests that in the case that S con=
tains private fields, the MEMBERS_T&lt;S&gt; class only allow access to the=
 members-of-S tuple to S and friends of S. For this the author proposes to =
add all the friend declarations in S to MEMBERS_T&lt;S&gt; in some way, may=
be through compiler magic.</div><div><br></div><div>This lead me to think a=
bout a (as generally useful as possible) way this could be archived. As is =
stated in the standard ([class.friend]p10), a friend declaration has no tra=
nsitive effect.</div><div><br></div><div>I propose adding a new friend decl=
aration directive, something like "friend <strong>import</strong> &lt;class=
-type&gt;", that differs in this regard and has the effect of adding ("impo=
rting") all the friend declarations in &lt;class-type&gt; into the current =
(class) context.</div><div><br></div><div>As "<strong>import</strong>" is n=
o standard C++ keyword, I personally favor using "<strong>using</strong>" i=
nstead, with "<strong>inline</strong>" also a possibility.</div><div><br></=
div><div>For a motivating example see N3326, which I think can be represent=
ed by something like this:</div><div><br></div><div>class A {</div><div><di=
v style=3D"margin-left: 40px !important;">
<div>int private_m;</div><div>friend void some_free_function();<br></div></=
div></div><div>};</div><div><br></div><div>template&lt;class T&gt; </div><d=
iv>class MEMBER_T {</div><div><div style=3D"margin-left: 40px !important;">
<div>// for A: std::tuple&lt;int&amp;&gt;</div><div> typedef std::tuple&lt;=
....&gt; all_members_tuple;</div><div> <br></div><div>// equivalent to "frie=
nd T" and all of T's friend declarations</div><div> friend <strong>using</s=
trong> T;</div><div> <br></div><div>// similar to std::tie(t_inst.private_m=
) in this case</div><div> // note that this function is private to guard ag=
ainst unrestricted</div><div> // access to private members of T</div><div>s=
tatic all_members_tuple members(T&amp; t_inst);<br></div></div></div><div>}=
;</div><div><br></div><div>void some_free_function() </div><div>{</div><div=
 style=3D"margin-left: 40px !important;">A a_inst;</div><div style=3D"margi=
n-left: 40px !important;">auto a_as_tuple =3D MEMBER_T&lt;A&gt;::members(a_=
inst); // Okay!</div><div style=3D"margin-left: 40px !important;">
get&lt;0&gt;(a_as_tuple) =3D 42;
</div><div style=3D"margin-left: 40px !important;">assert(a_inst.private_m =
=3D=3D 42);</div><div>}</div><div><br></div><div>In practice this should be=
 most useful for serialization functions that are privileged through "frien=
d" by a class to serialize them. Then these serialization functions can als=
o use a MEMBER_T-like reflection facility to get access to the private memb=
ers, without MEMBER_T mentioning them explicitly or just providing purely u=
nrestricted access as is done in languages like C# and Java(?).</div><div><=
br></div><div>I would be very interested in feedback to this idea. Are ther=
e great concerns against a transitive friend declaration in general? Is thi=
s motivating example enough to warrant inclusion of something like this int=
o the standard?</div><div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/?hl=3Den">http://groups.google.com/a/isocpp.org/group/std-pro=
posals/?hl=3Den</a>.<br />
&nbsp;<br />
&nbsp;<br />

------=_Part_2768_31402384.1368535003868--

.