Topic: Refined friend
Author: Dejan Milosavljevic <dmilos@gmail.com>
Date: Mon, 23 Mar 2015 15:37:03 -0700 (PDT)
Raw View
------=_Part_973_1148847042.1427150223080
Content-Type: multipart/alternative;
boundary="----=_Part_974_646764717.1427150223080"
------=_Part_974_646764717.1427150223080
Content-Type: text/plain; charset=UTF-8
There is a cases when friends have to many access right.
It would be nice to limit that access.
Example:
class A{
public:
void set_value( int const& val );
int const& get_value()const;
protected:
void val_internal_set( int const& i );
private:
int int_value;
friend class B;
};
class B {
public:
void val_change( A & a ){
a.val_internal_set( 2 );
a.int_value = 4; //!< We do not want that, but it can be
accidentally on this place even with correct effects.
}
};
Changing to something like this will solve the problem:
class A{
// ... ... ...
friend void B::val_change() *>> void val_internal_set( int const& i );*
};
More and in details explanation can be found in attachment.
--
---
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 email 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-proposals/.
------=_Part_974_646764717.1427150223080
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>There is a cases when <font face=3D"courier new,monos=
pace">friend<font face=3D"arial,sans-serif">s have to many access right.</f=
ont></font></div><div><br></div><div>It would be nice to limit that access.=
</div><div><br></div><div>Example:</div><div><br></div><div><font face=3D"c=
ourier new,monospace">class A{<br> public:<br>  =
; void set_value( int const& val );<br> i=
nt const& get_value()const;</font></div><div><font face=3D"courier new,=
monospace"> protected:<br> void val_int=
ernal_set( int const& i );<br> private:<br> &nbs=
p; int int_value;<br> friend class B;<br> };</font>=
</div><div><font face=3D"Courier New"><br></font></div><div><font face=3D"c=
ourier new,monospace"> class B {<br> public:<br> &nbs=
p; void val_change( A & a ){<br> &nb=
sp; a.val_internal_set( 2 );<br> &=
nbsp; a.int_value =3D 4; //!< We do not want tha=
t, but it can be accidentally on this place even with correct effects.<br>&=
nbsp; }<br> };</font></div><div><font face=3D"courier new,=
monospace"><br></font></div><div><font face=3D"arial,sans-serif">Changing t=
o something like this will solve the problem:</font></div><div><br></div><d=
iv><font face=3D"Courier New">class A{</font></div><div><font face=3D"Couri=
er New">// ... ... ...</font></div><div><font face=3D"Courier New"><div>fri=
end void B::val_change() <strong>>> void val_internal_set( int const&=
amp; i );</strong> </div></font></div><div><font face=3D"Courier New">};</f=
ont></div><p><br></p><div><font face=3D"arial,sans-serif">More and in detai=
ls explanation can be found in attachment.</font><br></div><div><font face=
=3D"Courier New"><br></font></div><div><font face=3D"Courier New"><br></fon=
t></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_974_646764717.1427150223080--
------=_Part_973_1148847042.1427150223080
Content-Type: text/html; charset=US-ASCII; name=rf.html
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename=rf.html
X-Attachment-Id: 14ecedef-fb88-413d-9110-186a3b1d2b56
Content-ID: <14ecedef-fb88-413d-9110-186a3b1d2b56>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>[C++]Refined friend(s).</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="Author" content="Dejan D. M. R. Milosavljevic" />
<meta name="Reply-to" content="office@ddmrm.com" />
<meta name="resource-type" content="document" />
<meta name="URL" content="http://www.ddmrm.com" />
<meta name="revisit-after" content="45 days" />
<meta name="Keywords" content="c++ proposal" />
<style type="text/css">
<!--
body {
margin-top: 20mm;
margin-right: 18mm;
margin-bottom: 20mm;
margin-left: 18mm;
border-width: 0;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
padding-left: 0px;
margin: 0;
vertical-align: baseline;
font-size:16px;
}
table {
vertical-align: baseline;
}
..paragraf {
text-indent: 10pt;
}
..IndentedBlock3ex {
margin-left: 3ex;
}
..IndentedBlock2ex {
margin-left: 2ex;
}
..IndentedBlock1ex {
margin-left: 1ex;
}
..NovaStranica {
page-break-before: auto;
page-break-after: always;
}
..NaslovStranice
{
font-size:30px;
font-weight:bold;
}
..NaslovGlavni
{
font-size:28px;
font-weight:bold;
}
..NaslovPod
{
font-size: 22px;
font-weight:bold;
}
..Naslovcic
{
font-size: 22px;
font-weight:bold;
}
..TextObican
{
font-size: 15px;
}
..TOCItem
{
font-size:18px;
font-weight:bold;
}
..NaslovDefinicije
{
font-size: 10;
}
..TextCode
{
font-size: 12px;
}
-->
</style>
</head>
<body bgcolor="#FFFFFF" text="#000000" class="TextObican">
<h1 align="center" > <div class="NaslovStranice">Refined friend(s)</div> </h1>
<table border="0" width="100%">
<tr>
<td width="100%"> </td>
<td nowrap="nowrap">
Document number: <br>
Date: <br>
Reply to:<br>
<br>
</td>
<td nowrap="nowrap">
NXXXX<br>
2015/03/22<br>
Dejan D.M. Milosavljevic<br>
(dmilos at gmail dot com)<br>
</td>
<td width="10%"> </td>
</tr>
</table>
<dl>
<dt><div class="NaslovGlavni">Table of Contents.</div></dt>
<dd>
<ul>
<li><div class="TOCItem">I. Abstract</div></li>
<li><div class="TOCItem">II. Motivation</div></li>
<li><div class="TOCItem">III. Solution</div>
<ul>
<li><div class="TOCItem">Pattern Refinement and mixing of '>>' and '!>>'</div></li>
</ul>
</li>
<li><div class="TOCItem">IV. Syntax</div>
<ul>
<li><div class="TOCItem">Constraints</div></li>
<li><div class="TOCItem">Other Syntax That Fails</div></li>
</ul>
</li>
<li><div class="TOCItem">V. Summary</div></li>
<li><div class="TOCItem">VI. Impact On the Standard</div></li>
</ul>
</dd>
<dt><div class="NaslovGlavni">I. Abstract</div></dt>
<dd>
Making friends allows them to use private and protected members.<br>
This refinement restrict accessibility in two ways 'access only to' or 'access to all except to'.
</dd>
<dt><div class="NaslovGlavni">II. Motivation</div></dt>
<dd>
<code>protected</code> and <code>private</code> make limitation of access to class members.<br>
<code>friend</code> make exception to that by granting complete access.<br>
In some cases there is need to limit access or to have something like '<i>grant access only to</i>' or '<i>grant access to all except to</i>'.
<dl>
<dt>Problem:</dt>
<dd>[<i>Example</i>:
<code><pre class="TextCode">
class A{
public:
void set_value( int const& val );
int const& get_value()const;
protected:
void val_internal_set( int const& i );
private:
int int_value;
friend class B;
};
class B {
public:
void val_change( A & a ){
a.val_internal_set( 2 );
<u>a.int_value = 4; <b>//!< We do not want that, but it can be accidentally on this place even with correct effects.</b></u>
}
};</pre></code>
—<i>end example</i>]<br><br>
</dd>
<dt>Slightly refined, but <code>B::val_change</code>, has complete access. <br>
Problem still exists. Compiler will not emit error.
In this case we actuality need limitation in opposite direction.
</dt>
<dd>
[<i>Example</i>:
<code><pre class="TextCode">
class A{
// ... ... ...
friend class B::val_change;
};</pre></code>
—<i>end example</i>]
<br>
</dd>
</dl>
In here, refinement is not enough and not good. class B still can access to <code>A::val_internal_set</code>.<br>
We want to grant access only to <code>A::val_internal_set</code> and not to other members.<br>
This will allow us to appropriately implement <code>B::val_change</code> knowing that ( by design ) <code> class B</code> ( or <code>B::val_change</code>) can access to <code>A::val_internal_set</code> and not to other members.
<br><br>
<p class="NovaStranica"></p>
</dd>
<dt><div class="NaslovGlavni">III. Solution</div></dt>
<dd>
<dl>
<dt>
Exact refinement by explicit expressing which members/functions <code>friend</code>s can access or not. </dt>
<dd>
[<i>Example</i>:
<blockquote>
<code><pre class="TextCode">class A{
// ... ... ...
protected:
void val_internal_set( int const& i );
private:
int int_value;
protected:
void float_internal_set( float const& f );
private:
float float_value;
protected:
void string_internal_set( std::string const& s );
private:
std::string string_value;
// B::val_change can use only to val_internal_set and float_internal_set.
friend void B::val_change()<b> >> void val_internal_set( int const& i ) </b>
<b> >> void float_internal_set( float const& f )</b>;
// C::val_change() can use only to float_internal_set.
friend void C::val_change()<b> >> void float_internal_set( float const& f )</b>;
// D::val_change() can not use string_value but can use other members.
friend void D::val_change()<b> !>> string_value</b>;
};
class B {
public:
void val_change( A & a ){
a.val_internal_set( 4 ); //!< OK
a.int_value = 2; //!< Error can not use
}
};
class C {
public:
void val_change( A & a ){
a.float_internal_set( 4 ); //!< OK
a.val_internal_set( 2 ); //!< Error can not use
}
};
class D {
public:
void val_change( A & a ){
a.val_internal_set( 4 ); //!< OK
a.float_internal_set( 2 ); //!< OK
a.string_value = "abc"; //!< Error can not use
}
};</pre></code>
</blockquote>
—<i>end example</i>]
</dd>
<dt> <div class="NaslovPod">Pattern Refinement and mixing of '>>' and '!>>'</div></dt>
<dd>
<br>In brief: Bad idea! <br><br>
[<i>Example</i>:
<code><pre class="TextCode">
class A{
// Access to all protected functions and to string_value
friend class X >> protected !>> string_value;
// Access to all private functions and not to string_value
friend class X >> private !>> string_value;
};</pre></code>
—<i>end example</i>]
<br><br>
This kind of refinement tend to be code bloating. Can easily cause mistakes during code inspection/review like misunderstanding.<br>
During developing this refinement can be to wide to catch/control our intention/design.<br>
In this case I think that it is better to make this simple to to level of '<i>grant access only to</i>' or '<i>grant access to all except to</i>'.<br>
Eve further mixing of '>>' and '!>>' in any way can make only confusion of what type of refinement we want e.g. make statement ambiguous.
</dd>
</dl>
<p class="NovaStranica"></p>
</dd>
<dt class ="NaslovGlavni">IV. Syntax</dt>
<dd>
<dl>
<dt><i>friend-declaration:</i></dt>
<dd><code>friend</code> <i>friend-specifier</i> ( '>>' <i>friend-member-declaration</i> )<sub>zero-or-more</sub> ';'</dd>
<dd><code>friend</code> <i>friend-specifier</i> ( '!' '>>' <i>friend-member-declaration</i> )<sub>zero-or-more</sub> ';'</dd>
<dt><i>friend-specifier:</i></dt>
<dd><i>elaborated-type-specifier</i></dd>
<dd><i>simple-type-specifier</i></dd>
<dd><i>typename-specifier</i></dd>
<dt><i>friend-member-declaration:</i></dt>
<dd><i>data-member-declaration</i> </dd>
<dd><i>function-member-declaration</i> </dd>
<dd><i>type-member-declaration</i> </dd>
<dd><i>enumerator-member-declaration</i> </dd>
<dt><i>data-member-declaration:</i></dt>
<dd><i>identifier</i> </dd>
<dt><i>function-member-declaration:</i></dt>
<dd><i>function-declarator</i> </dd>
<dt><i>type-member-declaration</i> </dt>
<dd><i>identifier</i></dd>
<dt><i>enumerator-member-declaration:</i></dt>
<dd><i>identifier</i> </dd>
</dl>
Note: '!>>' is not new token. It is two tokens '!' and '>>'.
<dl>
<dt><div class="NaslovPod">Constraints</div></dt>
<dd>
<dl>
<dt>Friend refinement for some class/function shall appears only once.</dt>
<dd>
[<i>Example</i>:
<pre class="TextCode" >class A {
public:
// <i>ill-formed. Double friend refinement of B::val_change().</i>
friend void B::val_change()<b> >> void val_internal_set( int & i ) </b>
friend void B::val_change()<b> >> void float_internal_set( int & i ) </b>;
// <i>OK. This is not refinement.</i>
friend class E;
friend class E;
};</pre>—<i>end example</i>]
</dd>
<dt> <div class="Naslovcic">Effects:</div></dt>
<dd>
<ul>
<li>Prevent abusing by making endless list.</li>
<li>Prevent of scattering one friend-specifier to several different places.</li>
<li>In case that list start to become large this will show obvious flaw in design.</li>
</ul>
</dd>
</dl>
</dd>
<dt><div class="NaslovPod">Other Syntax That Fails</div></dt>
<dd>
<dl>
<dt><div class="Naslovcic">'->'</div></dt>
<dd>
In here we obviously have problem with new function declaration syntax.
<blockquote>
[<i>Example</i>:
<pre class="TextCode" >class A {
// ... ... ...
friend void B::val_change() -> val_internal_set( int const& i ) -> void
-> float_internal_set( float const& f ) -> void;
};</pre>—<i>end example</i>]</blockquote>
</dd>
<dt><div class="Naslovcic">' >>' vs ','</div></dt>
<dd>
Not so clearly visible/readable after we read first line.
<blockquote>
[<i>Example</i>:
<pre class="TextCode" >class A {
// ... ... ...
friend void B::val_change() >> void val_internal_set( int const& i )
, void float_internal_set( float const& f );
};</pre>—<i>end example</i>]</blockquote>
</dd>
<dt><div class="Naslovcic">'>> { }'</div></dt>
<dd>
It can be misunderstand as function definition.
<blockquote>
[<i>Example</i>:
<pre class="TextCode" >class A {
// ... ... ...
friend void B::val_change() >> { void val_internal_set( int const& i )
, void float_internal_set( float const& f ); }
};</pre>—<i>end example</i>]</blockquote>
Without >> this is more worse. It is look like function definition.
<blockquote>
[<i>Example</i>:
<pre class="TextCode" >class A {
// ... ... ...
friend void B::val_change() { void val_internal_set( int const& i )
, void float_internal_set( float const& f ); }
};</pre>—<i>end example</i>]</blockquote>
</dd>
<dt><div class="Naslovcic">'[ ..., ... ]'</div></dt>
<dd>
Might be understand as array access.
<blockquote>
[<i>Example</i>:
<pre class="TextCode" >class A {
// ... ... ...
friend void B::val_change() >> [ void val_internal_set( int const& i )
, void float_internal_set( float const& f ) ] ;
};</pre>—<i>end example</i>]</blockquote>
Without '>>' things look much worse.
<blockquote>
[<i>Example</i>:
<pre class="TextCode" >class A {
// ... ... ...
friend void B::val_change() [ void val_internal_set( int const& i )
, void float_internal_set( float const& f ) ] ;
};</pre>—<i>end example</i>]</blockquote>
</dd>
</dl>
</dd>
</dl>
<p class="NovaStranica"></p>
</dd>
<dt><div class="NaslovGlavni">V. Summary</div></dt>
<dd>
<dl>
<dt>Access to all</dt>
<dd>By using friend specifier as usual.</dd>
<dt>No access at all</dt>
<dd>Jut do not use friend specifier.</dd>
<dt>Access to some members</dt>
<dd>By using '>>'</dd>
<dt>Not to access to some members</dt>
<dd>By using '!' '>>' </dd>
</dl>
</dd>
<dt><div class="NaslovGlavni">VI. Impact On the Standard</div></dt>
<dd>
<dl>
<dt> <div class="NaslovPod ">Core</div> </dt>
<dd>No effect.<br>
No new keywords. <br>
No new tokens. <br>
No changes to old syntax. <br>
Pure extension. <br>
Backward compatible. By design old declaration have same interpretation as described in ISO/IEC 14882 Second edition 2003-10-15.
</dd>
<dt><div class="NaslovPod ">Library</div></dt>
<dd>No effect.</dd>
<dt><div class="NaslovPod ">Existing code.</div></dt>
<dd>No effect.<br>
</dl>
</dd>
</dl>
<hr shade width="100%" align="center">
</body>
</html>
------=_Part_973_1148847042.1427150223080--
.
Author: =?UTF-8?Q?David_Rodr=C3=ADguez_Ibeas?= <dibeas@ieee.org>
Date: Mon, 23 Mar 2015 21:38:18 -0400
Raw View
--089e01176fe154afd50511fed64c
Content-Type: text/plain; charset=UTF-8
I understand that you want to befriend an external function but provide
access to only *one* (or a subset?) of the private interface (`protected`
is only relevant to inheritance). I have wanted something like that in the
past, and found a solution within the standard, although I must admit that
at the end of the day I have always found a different design that I
considered better at the time, but here's the sketch of the solution:
class A {
private:
void set_value(int val);
int int_value;
public:
class AccessorForB {
static void set_value(A& a, int value) {
a.set_value(value);
}
friend void B::val_change();
};
};
class B {
public:
void val_change(A& a) {
A::AccessorForB::set_value(a, 2);
}
};
The key there is that you create a helper class, `AccessorForB` that is
fully within your control, and you provide the necessary accessors to the
`A` class, but you make those accessors `private` and grant access to `B`.
Because friendship is not transitive that grants access only to the parts
of `A` that you want.
On Mon, Mar 23, 2015 at 6:37 PM, Dejan Milosavljevic <dmilos@gmail.com>
wrote:
> There is a cases when friends have to many access right.
>
> It would be nice to limit that access.
>
> Example:
>
> class A{
> public:
> void set_value( int const& val );
> int const& get_value()const;
> protected:
> void val_internal_set( int const& i );
> private:
> int int_value;
> friend class B;
> };
>
> class B {
> public:
> void val_change( A & a ){
> a.val_internal_set( 2 );
> a.int_value = 4; //!< We do not want that, but it can be
> accidentally on this place even with correct effects.
> }
> };
>
> Changing to something like this will solve the problem:
>
> class A{
> // ... ... ...
> friend void B::val_change() *>> void val_internal_set( int const& i );*
> };
>
>
> More and in details explanation can be found in attachment.
>
>
> --
>
> ---
> 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
> email 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-proposals/.
>
--
---
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 email 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-proposals/.
--089e01176fe154afd50511fed64c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I understand that you want to befriend an external functio=
n but provide access to only *one* (or a subset?) of the private interface =
(`protected` is only relevant to inheritance).=C2=A0 I have wanted somethin=
g like that in the past, and found a solution within the standard, although=
I must admit that at the end of the day I have always found a different de=
sign that I considered better at the time, but here's the sketch of the=
solution:<div><br></div><div>class A {</div><div>=C2=A0 =C2=A0private:</di=
v><div>=C2=A0 =C2=A0 =C2=A0void set_value(int val);</div><div>=C2=A0 =C2=A0=
=C2=A0int int_value;</div><div>=C2=A0 =C2=A0public:</div><div>=C2=A0 =C2=
=A0 =C2=A0class AccessorForB {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 static=
void set_value(A& a, int value) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0a.set_value(value);</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
}</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 friend void B::val_change();</div><=
div>=C2=A0 =C2=A0 =C2=A0};</div><div>};</div><div>class B {</div><div>=C2=
=A0 public:</div><div>=C2=A0 =C2=A0 =C2=A0void val_change(A& a) {</div>=
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 A::AccessorForB::set_value(a, 2);</div><di=
v>=C2=A0 =C2=A0 =C2=A0}</div><div>};</div><div><br></div><div>The key there=
is that you create a helper class, `AccessorForB` that is fully within you=
r control, and you provide the necessary accessors to the `A` class, but yo=
u make those accessors `private` and grant access to `B`.=C2=A0 Because fri=
endship is not transitive that grants access only to the parts of `A` that =
you want.</div></div><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Mon, Mar 23, 2015 at 6:37 PM, Dejan Milosavljevic <span dir=3D"ltr">=
<<a href=3D"mailto:dmilos@gmail.com" target=3D"_blank">dmilos@gmail.com<=
/a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv>There is a cases when <font face=3D"courier new,monospace">friend<font f=
ace=3D"arial,sans-serif">s have to many access right.</font></font></div><d=
iv><br></div><div>It would be nice to limit that access.</div><div><br></di=
v><div>Example:</div><div><br></div><div><font face=3D"courier new,monospac=
e">class A{<br>=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0=C2=A0 void set_va=
lue( int const& val );<br>=C2=A0=C2=A0=C2=A0=C2=A0 int const& get_v=
alue()const;</font></div><div><font face=3D"courier new,monospace">=C2=A0=
=C2=A0 protected:<br>=C2=A0=C2=A0=C2=A0=C2=A0 void val_internal_set( int co=
nst& i );<br>=C2=A0=C2=A0 private:<br>=C2=A0=C2=A0=C2=A0=C2=A0 int int_=
value;<br>=C2=A0=C2=A0 friend class B;<br>=C2=A0 };</font></div><div><font =
face=3D"Courier New"><br></font></div><div><font face=3D"courier new,monosp=
ace">=C2=A0class B {<br>=C2=A0=C2=A0 public:<br>=C2=A0=C2=A0=C2=A0 void val=
_change( A & a ){<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 a.val_i=
nternal_set( 2 );<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 a.int_value=
=3D 4;=C2=A0=C2=A0=C2=A0=C2=A0 //!< We do not want that, but it can be =
accidentally on this place even with correct effects.<br>=C2=A0=C2=A0=C2=A0=
}<br>=C2=A0};</font></div><div><font face=3D"courier new,monospace"><br></=
font></div><div><font face=3D"arial,sans-serif">Changing to something like =
this will solve the problem:</font></div><div><br></div><div><font face=3D"=
Courier New">class A{</font></div><div><font face=3D"Courier New">// ... ..=
.. ...</font></div><div><font face=3D"Courier New"><div>friend void B::val_c=
hange() <strong>>> void val_internal_set( int const& i );</strong=
> </div></font></div><div><font face=3D"Courier New">};</font></div><p><br>=
</p><div><font face=3D"arial,sans-serif">More and in details explanation ca=
n be found in attachment.</font><span class=3D"HOEnZb"><font color=3D"#8888=
88"><br></font></span></div><span class=3D"HOEnZb"><font color=3D"#888888">=
<div><font face=3D"Courier New"><br></font></div><div><font face=3D"Courier=
New"><br></font></div></font></span></div><span class=3D"HOEnZb"><font col=
or=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01176fe154afd50511fed64c--
.
Author: David Krauss <potswa@gmail.com>
Date: Tue, 24 Mar 2015 13:25:47 +0800
Raw View
--Apple-Mail=_D7CCC11F-AC4D-4ADE-9C27-FE840088FA9C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9303=E2=80=9324, at 9:38 AM, David Rodr=C3=ADguez Ibeas <di=
beas@ieee.org> wrote:
>=20
> class A {
> private:
> void set_value(int val);
> int int_value;
> public:
> class AccessorForB {
> static void set_value(A& a, int value) {
> a.set_value(value);
> }
> friend void B::val_change();
> };
> };
> class B {
> public:
> void val_change(A& a) {
> A::AccessorForB::set_value(a, 2);
> }
> };
>=20
> The key there is that you create a helper class, `AccessorForB` that is f=
ully within your control, and you provide the necessary accessors to the `A=
` class, but you make those accessors `private` and grant access to `B`. B=
ecause friendship is not transitive that grants access only to the parts of=
`A` that you want.
A slight modification can avoid the explicit qualification. Replace the nes=
ted accessor with a base:
struct B {
void val_change( class A & a );
};
class AccessorForB {
void set_value(int value);
friend void B::val_change( A & );
};
class A : public AccessorForB {
friend class AccessorForB; // OK: AccessorForB is within the same local=
implementation.
int int_value;
};
void AccessorForB::set_value(int value) {
static_cast<A*>(this)->int_value =3D value;
}
void B::val_change(A& a) {
a.set_value(2);
}
--=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/.
--Apple-Mail=_D7CCC11F-AC4D-4ADE-9C27-FE840088FA9C
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9303=
=E2=80=9324, at 9:38 AM, David Rodr=C3=ADguez Ibeas <<a href=3D"mailto:d=
ibeas@ieee.org" class=3D"">dibeas@ieee.org</a>> wrote:</div><br class=3D=
"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" style=3D"font-=
family: Helvetica; font-size: 12px; font-style: normal; font-variant: norma=
l; font-weight: normal; letter-spacing: normal; line-height: normal; orphan=
s: auto; text-align: start; text-indent: 0px; text-transform: none; white-s=
pace: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0=
px;" class=3D""><div class=3D"">class A {</div><div class=3D"">  =
;private:</div><div class=3D""> void set_value(int val);=
</div><div class=3D""> int int_value;</div><div class=3D=
""> public:</div><div class=3D""> class Acce=
ssorForB {</div><div class=3D""> static void set=
_value(A& a, int value) {</div><div class=3D""> &nb=
sp; a.set_value(value);</div><div class=3D""> &nb=
sp; }</div><div class=3D""> friend void B=
::val_change();</div><div class=3D""> };</div><div class=
=3D"">};</div><div class=3D"">class B {</div><div class=3D""> public:=
</div><div class=3D""> void val_change(A& a) {</div>=
<div class=3D""> A::AccessorForB::set_value(a, 2=
);</div><div class=3D""> }</div><div class=3D"">};</div>=
<div class=3D""><br class=3D""></div><div class=3D"">The key there is that =
you create a helper class, `AccessorForB` that is fully within your control=
, and you provide the necessary accessors to the `A` class, but you make th=
ose accessors `private` and grant access to `B`. Because friendship i=
s not transitive that grants access only to the parts of `A` that you want.=
</div></div></div></blockquote><div><br class=3D""></div></div>A slight mod=
ification can avoid the explicit qualification. Replace the nested accessor=
with a base:<div class=3D""><br class=3D""></div><div class=3D""><div clas=
s=3D""><font face=3D"Courier" class=3D"">struct B {</font></div><div class=
=3D""><font face=3D"Courier" class=3D""> void val_change( clas=
s A & a );</font></div><div class=3D""><font face=3D"Courier" class=3D"=
">};</font></div><div class=3D""><font face=3D"Courier" class=3D""><br clas=
s=3D""></font></div><div class=3D""><font face=3D"Courier" class=3D"">class=
AccessorForB {</font></div><div class=3D""><font face=3D"Courier" class=3D=
""> void set_value(int value);</font></div><div class=3D""><fo=
nt face=3D"Courier" class=3D""> friend void B::val_change( A &=
amp; );</font></div><div class=3D""><font face=3D"Courier" class=3D"">};</f=
ont></div><div class=3D""><font face=3D"Courier" class=3D"">class A : publi=
c AccessorForB {</font></div><div class=3D""><font face=3D"Courier" class=
=3D""> friend class AccessorForB; // OK: AccessorForB is withi=
n the same local implementation.</font></div><div class=3D""><font face=3D"=
Courier" class=3D""> int int_value;</font></div><div class=3D"=
"><font face=3D"Courier" class=3D"">};</font></div><div class=3D""><font fa=
ce=3D"Courier" class=3D""><br class=3D""></font></div><div class=3D""><font=
face=3D"Courier" class=3D"">void AccessorForB::set_value(int value) {</fon=
t></div><div class=3D""><font face=3D"Courier" class=3D""> sta=
tic_cast<A*>(this)->int_value =3D value;</font></div><div class=3D=
""><font face=3D"Courier" class=3D"">}</font></div><div class=3D""><font fa=
ce=3D"Courier" class=3D""><br class=3D""></font></div><div class=3D""><font=
face=3D"Courier" class=3D"">void B::val_change(A& a) {</font></div><di=
v class=3D""><font face=3D"Courier" class=3D""> a.set_va=
lue(2);</font></div><div class=3D""><font face=3D"Courier" class=3D"">}</fo=
nt></div></div><div class=3D""><br class=3D""></div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_D7CCC11F-AC4D-4ADE-9C27-FE840088FA9C--
.
Author: Dejan Milosavljevic <dmilos@gmail.com>
Date: Tue, 24 Mar 2015 15:41:26 -0700 (PDT)
Raw View
------=_Part_1010_1122093432.1427236886626
Content-Type: multipart/alternative;
boundary="----=_Part_1011_1970407317.1427236886626"
------=_Part_1011_1970407317.1427236886626
Content-Type: text/plain; charset=UTF-8
Obviously there is pattern for making refined friend within standard.
If you want to use extensively you will start with copy/paste or making
additional class(es) and putting them in some library.
In copy/paste case there is several problems:
Problem arrives also when you want to add more friend class. This will give
us linear mini class explosion.
Another problem when we want to rename A or B or both proxy has to be
renamed also.
If someone else read the code it would be very nice to have additional
comment to explain purpose and that is few lines more.
In library case problems are similar:
More code to maintained, means: documenting, improving, debugging.
Using will require intervention on several places. In constructor, probably
making additional members.
Every additional members in some cases can consume too much memory e.g.
Color has Image for friend.
This additional handling/maintaining of proxy class for such a small thing
is not so practical.
Every of above reason will discourage using of 'within in standard'
solution.
This proposal eliminates all that problems. Just line or two in comparing
with ( few ) dozen.
Also giving too much access by declaring friend to some class also
discourage usage of standard friend.
Several times I have to abandon usage of friend due to 'too much access'.
>
>
--
---
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 email 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-proposals/.
------=_Part_1011_1970407317.1427236886626
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Obviously there is pattern for making refined friend withi=
n standard.<br>If you want to use extensively you will start with copy/past=
e or making additional class(es) and putting them in some library.<br><br>I=
n copy/paste case there is several problems:<br> Problem arrives also wh=
en you want to add more friend class. This will give us linear mini class e=
xplosion.<br>Another problem when we want to rename A or B or both proxy ha=
s to be renamed also.<br>If someone else read the code it would be very nic=
e to have additional comment to explain purpose and that is few lines more.=
<br><br>In library case problems are similar:<br> More code to maintaine=
d, means: documenting, improving, debugging.<br>Using will require interven=
tion on several places. In constructor, probably making additional members.=
<br>Every additional members in some cases can consume too much memory e.g.=
Color has Image for friend.<br><br>This additional handling/maintaining of=
proxy class for such a small thing is not so practical.<br><br>Every of ab=
ove reason will discourage using of 'within in standard' solution.<br><br>T=
his proposal eliminates all that problems. Just line or two in comparing wi=
th ( few ) dozen.<br><br>Also giving too much access by declaring friend to=
some class also discourage usage of standard friend.<br>Several times I ha=
ve to abandon usage of friend due to 'too much access'.<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div><br><=
/div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1011_1970407317.1427236886626--
------=_Part_1010_1122093432.1427236886626--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 25 Mar 2015 18:29:52 +0200
Raw View
On 25 March 2015 at 00:41, Dejan Milosavljevic <dmilos@gmail.com> wrote:
> Obviously there is pattern for making refined friend within standard.
> If you want to use extensively you will start with copy/paste or making
> additional class(es) and putting them in some library.
Why would I use any kind of friends extensively, and why would I use these
refined-friends extensively? If I need narrow/refined friends often,
I'd say it's time
to rethink my design.
> In copy/paste case there is several problems:
> Problem arrives also when you want to add more friend class. This will give
> us linear mini class explosion.
Compared to an "explosion" of refined-friend declarations?
> Another problem when we want to rename A or B or both proxy has to be
> renamed also.
> If someone else read the code it would be very nice to have additional
> comment to explain purpose and that is few lines more.
Compared to "few lines more" of refined-friend declarations?
> In library case problems are similar:
> More code to maintained, means: documenting, improving, debugging.
> Using will require intervention on several places. In constructor, probably
> making additional members.
I don't quite follow. Moving 1 to N members into a subobject type
doesn't necessarily
complicate the initialization that the constructor does, it may
actually simplify it.
> Every additional members in some cases can consume too much memory e.g.
> Color has Image for friend.
How does that increase memory consumption?
> This additional handling/maintaining of proxy class for such a small thing
> is not so practical.
Yet it provides an abstraction between the friend and its ultimate
target, allowing
the proxy to change without changing either end, like a Memento pattern.
> This proposal eliminates all that problems. Just line or two in comparing
> with ( few ) dozen.
Yet it adds a very specific syntax for an arguably rare use case.
> Also giving too much access by declaring friend to some class also
> discourage usage of standard friend.
Again, I fail to see why that's so bad.
> Several times I have to abandon usage of friend due to 'too much access'.
Ditto.
--
---
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 email 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-proposals/.
.
Author: Dejan Milosavljevic <dmilos@gmail.com>
Date: Wed, 25 Mar 2015 16:27:30 -0700 (PDT)
Raw View
------=_Part_4765_624974472.1427326050499
Content-Type: multipart/alternative;
boundary="----=_Part_4766_603433427.1427326050499"
------=_Part_4766_603433427.1427326050499
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
> Why would I use any kind of friends extensively,
> and why would I use these refined-friends extensively?
> If I need narrow/refined friends often, I'd say it's time to rethink my=
=20
design.
It is up to you to decide what do you want to use.
Some programmers do not use exception at all. In a contrary some of them=20
use very often.
I see both code and I have no complains.
For one problem you can have more than one good solutions.
> > In copy/paste case there is several problems:
> > Problem arrives also when you want to add more friend class. This will=
=20
give
> > us linear mini class explosion.
>
> Compared to an "explosion" of refined-friend declarations?
Depend what do you see as "explosion".
In David Krauss there is AccessorForB. What if design require another=20
AccessorForC, AccessorForD.
It is much simple to use refined-friend.
> > Another problem when we want to rename A or B or both proxy has to be
> > renamed also.
> > If someone else read the code it would be very nice to have additional
> > comment to explain purpose and that is few lines more.
>
> Compared to "few lines more" of refined-friend declarations?
In David Kraus solution we have 7 ( seven ) lines of code.
In David Rodr=C3=ADguez Ibeas 4 ( four ).
refined-friend only 1 ( one ).
> ... complicate the initialization that the constructor does, it may
> actually simplify it.
Any unnecessary coding is complication. Specially for this case.
>> Every additional members in some cases can consume too much memory e.g.
>> Color has Image for friend.
> How does that increase memory consumption?
Purposely or not AccessorForB::set_value can be virtual.
Make a million instance of A. Few unnecessary bytes for *vtabel*=20
multiply with million.
> > This proposal eliminates all that problems. Just line or two in=20
comparing
> > with ( few ) dozen.
>
> Yet it adds a very specific syntax
Obviously.
> for an arguably rare use case.
For some people exceptions are arguably rare for some others are not.
Again, depend how do you wan to solve the problem.
> > Also giving too much access by declaring friend to some class also
> > discourage usage of standard friend.
>
> Again, I fail to see why that's so bad.
friend breaks encapsulation. Accidentally or not it is possible to use=20
other member avoiding original design.
Compiler will not warn or emit the error. With refined-friend you will have=
=20
error and that is the purpose of it.
--=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/.
------=_Part_4766_603433427.1427326050499
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p>> Why would I use any kind of friends extensively,<b=
r>> and why would I use these refined-friends extensively?<br>> If I =
need narrow/refined friends often, I'd say it's time to rethink my design.<=
/p><p>It is up to you to decide what do you want to use.<br>Some programmer=
s do not use exception at all. In a contrary some of them use very often.<b=
r>I see both code and I have no complains.<br>For one problem you can have =
more than one good solutions.</p><p>> > In copy/paste case there is s=
everal problems:<br>> > Problem arrives also when you want to add mor=
e friend class. This will give<br>> > us linear mini class explosion.=
<br>><br>> Compared to an "explosion" of refined-friend declarations?=
</p><p>Depend what do you see as "explosion".</p><p>In David Krauss there i=
s AccessorForB. What if design require another AccessorForC, AccessorForD.<=
br>It is much simple to use refined-friend.</p><p>> > Another problem=
when we want to rename A or B or both proxy has to be<br>> > renamed=
also.<br>> > If someone else read the code it would be very nice to =
have additional<br>> > comment to explain purpose and that is few lin=
es more.<br>><br>> Compared to "few lines more" of refined-friend dec=
larations?</p><p>In David Kraus solution we have 7 ( seven ) lines of code.=
<br>In David Rodr=C3=ADguez Ibeas 4 ( four ).<br>refined-friend only =
1 ( one ).</p><p>> ... complicate the initialization that the constructo=
r does, it may<br>> actually simplify it.<br>Any unnecessary coding is c=
omplication. Specially for this case.</p><p><br>>> Every additional m=
embers in some cases can consume too much memory e.g.<br>>> Color has=
Image for friend.<br>> How does that increase memory consumption?</p><p=
>Purposely or not AccessorForB::set_value can be virtual.<br>Make a m=
illion instance of A. Few unnecessary bytes for <em>vtabel</em> multiply&nb=
sp;with million.</p><p>> > This proposal eliminates all that problems=
.. Just line or two in comparing<br>> > with ( few ) dozen.<br>><br=
>> Yet it adds a very specific syntax</p><p>Obviously.</p><p>> for an=
arguably rare use case.</p><p>For some people exceptions are arguably rare=
for some others are not.<br>Again, depend how do you wan to solve the prob=
lem.</p><p>> > Also giving too much access by declaring friend to som=
e class also<br>> > discourage usage of standard friend.<br>><br>&=
gt; Again, I fail to see why that's so bad.</p><p><font face=3D"courier new=
,monospace">friend</font> breaks encapsulation. Accidentally or not it is p=
ossible to use other member avoiding original design.<br>Compiler will not =
warn or emit the error. With refined-friend you will have error and that is=
the purpose of it.<br></p></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4766_603433427.1427326050499--
------=_Part_4765_624974472.1427326050499--
.
Author: David Krauss <potswa@gmail.com>
Date: Thu, 26 Mar 2015 12:12:05 +0800
Raw View
--Apple-Mail=_52BB4464-BCFE-4249-B42B-9ECCFC23DA4D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9303=E2=80=9326, at 7:27 AM, Dejan Milosavljevic <dmilos@gm=
ail.com> wrote:
>=20
> In David Krauss there is AccessorForB. What if design require another Acc=
essorForC, AccessorForD.
>=20
> It is much simple to use refined-friend.
>=20
> In David Kraus solution we have 7 ( seven ) lines of code.
> In David Rodr=C3=ADguez Ibeas 4 ( four ).
> refined-friend only 1 ( one ).
>=20
Rodriguez=E2=80=99 and my solutions aren=E2=80=99t so different. I added so=
me forward declarations to correct errors in his example (which actually ca=
me from the proposal).
Factoring class functionality into single-use bases isn=E2=80=99t really to=
o unusual nor high-overhead. It=E2=80=99s also used for the empty base clas=
s optimization. It could be made a bit easier by allowing class definitions=
within base class lists.
struct B {
void val_change( class A & a );
};
class A : public class {
void set_value(int value) {
static_cast<A*>(this)->int_value =3D value;
}
friend void B::val_change( A & );
} {
int int_value;
};
void B::val_change(A& a) {
a.set_value(2);
}
The base class member function definitions can be processed together with t=
hose of the derived class, reducing the need for forward declarations. It=
=E2=80=99s pretty sensible to befriend all of struct B instead of one membe=
r function, and then this example doesn=E2=80=99t need any forward declarat=
ions.
There=E2=80=99s little need for access protection within such a base class;=
it might as well be treated as nested. In that case, the public can be dro=
pped from this example, and with it a little bit of RTTI overhead, since pr=
ivate bases are invisible to dynamic_cast.
Allow the base classes to be named with this syntax, let them share templat=
e parameters with the enclosing derived class, and let them be partially sp=
ecialized. Then this is applicable to the empty base class optimization too=
..
--=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/.
--Apple-Mail=_52BB4464-BCFE-4249-B42B-9ECCFC23DA4D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9303=
=E2=80=9326, at 7:27 AM, Dejan Milosavljevic <<a href=3D"mailto:dmilos@g=
mail.com" class=3D"">dmilos@gmail.com</a>> wrote:</div><br class=3D"Appl=
e-interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D""><p class=
=3D"">In David Krauss there is AccessorForB. What if design require another=
AccessorForC, AccessorForD.</p><p class=3D"">It is much simple to use refi=
ned-friend.</p><p class=3D""></p></div></div></blockquote><br class=3D""><b=
lockquote type=3D"cite" class=3D""><div class=3D""><div dir=3D"ltr" class=
=3D""><p class=3D"">In David Kraus solution we have 7 ( seven ) lines of co=
de.<br class=3D"">In David Rodr=C3=ADguez Ibeas 4 ( four ).<br class=
=3D"">refined-friend only 1 ( one ).</p></div></div></blockquote><div>Rodri=
guez=E2=80=99 and my solutions aren=E2=80=99t so different. I added some fo=
rward declarations to correct errors in his example (which actually came fr=
om the proposal).</div><div><br class=3D""></div><div>Factoring class funct=
ionality into single-use bases isn=E2=80=99t really too unusual nor high-ov=
erhead. It=E2=80=99s also used for the empty base class optimization. It co=
uld be made a bit easier by allowing class definitions within base class li=
sts.</div><div><br class=3D""></div><div><div class=3D""><font face=3D"Cour=
ier" class=3D"">struct B {</font></div><div class=3D""><font face=3D"Courie=
r" class=3D""> void val_change( class A & a );</font></div=
><div class=3D""><font face=3D"Courier" class=3D"">};</font></div><div clas=
s=3D""><font face=3D"Courier" class=3D""><br class=3D""></font></div><div c=
lass=3D""><span style=3D"font-family: Courier;" class=3D"">class A : public=
class {</span></div><div class=3D""><font face=3D"Courier" class=3D"">&nbs=
p; void set_value(int value) {</font></div><div class=3D""><font fac=
e=3D"Courier" class=3D""> static_cast<A*>(=
this)->int_value =3D value;</font></div><div class=3D""><font face=3D"Co=
urier" class=3D""> }</font></div><div class=3D""><font face=3D=
"Courier" class=3D""> friend void B::val_change( A & );</f=
ont></div><div class=3D""><font face=3D"Courier" class=3D"">} {</font></div=
><div class=3D""><span style=3D"font-family: Courier;" class=3D""> &n=
bsp; int int_value;</span></div><div class=3D""><font face=3D"Courier" clas=
s=3D"">};</font></div><div class=3D""><font face=3D"Courier" class=3D""><br=
class=3D""></font></div><div class=3D""><span style=3D"font-family: Courie=
r;" class=3D"">void B::val_change(A& a) {</span></div><div class=3D""><=
font face=3D"Courier" class=3D""> a.set_value(2);</font>=
</div><div class=3D""><font face=3D"Courier" class=3D"">}</font></div></div=
><div><br class=3D""></div>The base class member function definitions can b=
e processed together with those of the derived class, reducing the need for=
forward declarations. It=E2=80=99s pretty sensible to befriend all of <fon=
t face=3D"Courier" class=3D"">struct B</font> instead of one member functio=
n, and then this example doesn=E2=80=99t need any forward declarations.</di=
v><div><br class=3D""></div><div>There=E2=80=99s little need for access pro=
tection within such a base class; it might as well be treated as nested. In=
that case, the <font face=3D"Courier" class=3D"">public</font> can be drop=
ped from this example, and with it a little bit of RTTI overhead, since pri=
vate bases are invisible to <font face=3D"Courier" class=3D"">dynamic_cast<=
/font>.</div><div><br class=3D""></div><div>Allow the base classes to be na=
med with this syntax, let them share template parameters with the enclosing=
derived class, and let them be partially specialized. Then this is applica=
ble to the empty base class optimization too.</div></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_52BB4464-BCFE-4249-B42B-9ECCFC23DA4D--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 26 Mar 2015 14:51:42 +0200
Raw View
On 26 March 2015 at 01:27, Dejan Milosavljevic <dmilos@gmail.com> wrote:
>> Why would I use any kind of friends extensively,
>> and why would I use these refined-friends extensively?
>> If I need narrow/refined friends often, I'd say it's time to rethink my
>> design.
>
> It is up to you to decide what do you want to use.
> Some programmers do not use exception at all. In a contrary some of them =
use
> very often.
> I see both code and I have no complains.
> For one problem you can have more than one good solutions.
That fails to answer the question. What is the use case where such
narrow-friends
need to be used extensively, and why will the alternatives not do? The
motivation
of the proposal fails to deliver answers to those questions.
> In David Kraus solution we have 7 ( seven ) lines of code.
> In David Rodr=C3=ADguez Ibeas 4 ( four ).
> refined-friend only 1 ( one ).
Those solutions try to allow access to a member that is a plain member. The=
y
do not consider alternative ways, like having a subobject that is public
but has everything in it private, and declares the friends you need. In oth=
er
words, dividing the members differently. Such alternatives should be compar=
ed
to the proposed solution in the proposal.
>>> Every additional members in some cases can consume too much memory e.g.
>>> Color has Image for friend.
>> How does that increase memory consumption?
> Purposely or not AccessorForB::set_value can be virtual.
> Make a million instance of A. Few unnecessary bytes for vtabel multiply w=
ith
> million.
Then don't make a million instances of AccessorForB. There's no need for
Memento pattern implementations to be allocated if they are not needed.
>> Again, I fail to see why that's so bad.
> friend breaks encapsulation. Accidentally or not it is possible to use ot=
her
Friends do not break encapsulation, they provide controlled access to
a well-defined
set of classes that are explicitly declared.
> member avoiding original design.
> Compiler will not warn or emit the error. With refined-friend you will ha=
ve
> error and that is the purpose of it.
Yes, and there are other ways to get the same granularity. The onus is
on the proposal
to explain why it should get specific language support.
--=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/.
.
Author: Dejan Milosavljevic <dmilos@gmail.com>
Date: Thu, 26 Mar 2015 16:38:27 -0700 (PDT)
Raw View
------=_Part_223_239721172.1427413107478
Content-Type: multipart/alternative;
boundary="----=_Part_224_314416032.1427413107479"
------=_Part_224_314416032.1427413107479
Content-Type: text/plain; charset=UTF-8
> What is the use case where such narrow-friends need to be used
extensively, and why will the alternatives not do?
I do not see narrow-friends as something that must be used extensively like
we use const.
But when I use I'll like to make fine tune of that. Current friend fail on
that.
> Friends do not break encapsulation, ...
Not break to all, just to friend.
> The onus is on the proposal to explain why it should get specific
language support.
Less code. See above line counting. Leads to clarity of reading.
Better defining of relation between classes/functions.
>
>
--
---
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 email 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-proposals/.
------=_Part_224_314416032.1427413107479
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p>> What is the use case where such narrow-friends nee=
d to be used extensively, and why will the alternatives not do?<br>I do not=
see narrow-friends as something that must be used extensively like we use =
<font face=3D"courier new,monospace">const</font>.<br>But when I use I'll l=
ike to make fine tune of that. Current friend fail on that.</p><p>> Frie=
nds do not break encapsulation, ...<br>Not break to all, just to friend.</p=
><p>> The onus is on the proposal to explain why it should get specific =
language support. <br>Less code. See above line counting. Leads to clarity =
of reading.<br>Better defining of relation between classes/functions.<br></=
p><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; pad=
ding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1=
px; border-left-style: solid;"><br></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_224_314416032.1427413107479--
------=_Part_223_239721172.1427413107478--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Fri, 27 Mar 2015 14:55:02 -0400
Raw View
--089e0158c31a843309051249ab9b
Content-Type: text/plain; charset=UTF-8
On Thu, Mar 26, 2015 at 7:38 PM, Dejan Milosavljevic <dmilos@gmail.com>
wrote:
> > What is the use case where such narrow-friends need to be used
> extensively, and why will the alternatives not do?
> I do not see narrow-friends as something that must be used extensively
> like we use const.
>
And that is exactly why const gets a keyword, and narrow friend does not.
Similarly, as you mentioned earlier, exceptions: Exceptions, whether some
like/use them or not, tackle a very common and fundamental problem. Thus
they deserve time/energy and language to support them.
Narrow friend just isn't used enough.
> But when I use I'll like to make fine tune of that. Current friend fail on
> that.
>
You can easily argue that current friend is a failure. I mostly agree.
And I agree that a refined friend would better solve the problem that
current friend tried to solve. If I had to choose between current friend
and refined friend, I'd probably go with refined friend (if wasn't too
complicated, etc).
I just don't agree that it is a big enough problem to solve.
> > Friends do not break encapsulation, ...
> Not break to all, just to friend.
>
> > The onus is on the proposal to explain why it should get specific
> language support.
> Less code. See above line counting. Leads to clarity of reading.
> Better defining of relation between classes/functions.
>
Agree that those are valid reasons. But are they enough? Every item added
to the language has a cost. Many costs in fact. ie:
- time/energy of the committee, which is finite.
- In particular, the above means some other feature doesn't happen.
- complexity of the language. Even if a feature is simple or simpler than
what it replaces, it still *adds* to the size of the language, which is
already too complicated. (And due to backwards compatibility, everything
*adds*, nothing replaces, at least in the short/medium term).
Tony
--
---
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 email 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-proposals/.
--089e0158c31a843309051249ab9b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Thu, Mar 26, 2015 at 7:38 PM, Dejan Milosavljevic <span dir=3D"ltr">=
<<a href=3D"mailto:dmilos@gmail.com" target=3D"_blank">dmilos@gmail.com<=
/a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<div dir=3D"ltr"><p><span class=3D"">> What is the use case where such n=
arrow-friends need to be used extensively, and why will the alternatives no=
t do?<br></span>I do not see narrow-friends as something that must be used =
extensively like we use <font face=3D"courier new,monospace">const</font>.<=
br></p></div></blockquote><div><br>And that is exactly why const gets a key=
word, and narrow friend does not.<br><br></div><div>Similarly, as you menti=
oned earlier, exceptions: Exceptions, whether some like/use them or not, ta=
ckle a very common and fundamental problem. Thus they deserve time/energy a=
nd language to support them.<br><br></div><div>Narrow friend just isn't=
used enough.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);pad=
ding-left:1ex"><div dir=3D"ltr"><p>But when I use I'll like to make fin=
e tune of that. Current friend fail on that.</p></div></blockquote><div><br=
></div><div>You can easily argue that current friend is a failure.=C2=A0 I =
mostly agree.=C2=A0 And I agree that a refined friend would better solve th=
e problem that current friend tried to solve. If I had to choose between cu=
rrent friend and refined friend, I'd probably go with refined friend (i=
f wasn't too complicated, etc).<br><br></div><div>I just don't agre=
e that it is a big enough problem to solve.<br>=C2=A0<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><p>> Friends do n=
ot break encapsulation, ...<br>Not break to all, just to friend.</p><p><spa=
n class=3D"">> The onus is on the proposal to explain why it should get =
specific language support. <br></span>Less code. See above line counting. L=
eads to clarity of reading.<br>Better defining of relation between classes/=
functions.<br></p></div></blockquote><div><br></div><div>Agree that those a=
re valid reasons.=C2=A0 But are they enough?=C2=A0 Every item added to the =
language has a cost.=C2=A0 Many costs in fact. ie:<br><br></div><div>- time=
/energy of the committee, which is finite.<br>- In particular, the above me=
ans some other feature doesn't happen.<br></div><div dir=3D"ltr">- comp=
lexity of the language.=C2=A0 Even if a feature is simple or simpler than w=
hat it replaces, it still *adds* to the size of the language, which is alre=
ady too complicated. (And due to backwards compatibility, everything *adds*=
, nothing replaces, at least in the short/medium term).<br><br><br></div><d=
iv>Tony<br></div></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0158c31a843309051249ab9b--
.
Author: Dejan Milosavljevic <dmilos@gmail.com>
Date: Fri, 27 Mar 2015 16:13:28 -0700 (PDT)
Raw View
------=_Part_5_977650526.1427498008278
Content-Type: multipart/alternative;
boundary="----=_Part_6_975007285.1427498008278"
------=_Part_6_975007285.1427498008278
Content-Type: text/plain; charset=UTF-8
> I just don't agree that it is a big enough problem to solve.
That is the catch with friend.
We expect that every feature are equally used. Frankly nothing can match
usage of const.
By design friend fail on that. This proposal can rise up usage for a little
bit.
> time/energy of the committee, which is finite.
Yes you are right is it worth of effort.
I'll continue on this by making revision 2.
After few iteration it will be much easier to decide do we need this or not.
If not, we will have anti-proposal :)
It is cheaper to burn my time than engage whole committee.
> complexity of the language... And due to backwards compatibility ...
Agree.
I have idea of class interface extending that directly lead to bloat.
In some imaginare case after some time damage will be beyond repair.
Deprecation of that feature will be impossible.
Also I'd like to thanks to all by point me to important question for that I
need to provide more accurate answers:
1. Why should I use this?
2. Why should I frequently use? More then I use friend now.
3. Benefits.
4. Examples with practical usage.
If I miss something fill free to add.
Above we have abstract examples.
Her is text-book type:
class Fruit{
public:
int get_color(){ /* calculate color based on time and amount of
sweet_core */ return time + sweet_core; }
int const& get_sweet_core()const{ return sweet_core; }
void set_time( int const& t){ time = t; /* recalculate sweet_core*/
--sweet_core; }
int const& get_time( )const{ return time; }
protected:
int const& set_sweet_core( int & sc ){ sweet_core = sc; return
sweet_core; }
private:
int time=100;
int sweet_core=100;
friend Maggot >> set_sweet_core;
};
class Maggot{
public:
void eat( Fruit & f ){ while( f.set_sweet_core( f.get_sweet_core() - 1 )
); }
};
Fruit f;
Maggot m;
std::thread t1( [&](){ m.eat( f ); } );
std::thread t2( [&](){ while( 0 != f.get_sweet_core() ) f.set_time(
f.get_time()+1 ); } );
// ... .. ...
// ... ... ...
There is a data race. Ignore it.
Obviously time is not concern of Maggot but set_sweat_core is.
--
---
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 email 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-proposals/.
------=_Part_6_975007285.1427498008278
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p>> I just don't agree that it is a big enough problem=
to solve.</p><p>That is the catch with friend.<br>We expect that every fea=
ture are equally used. Frankly nothing can match usage of <font face=3D"cou=
rier new,monospace">const</font>.<br>By design friend fail on that. This pr=
oposal can rise up usage for a little bit.</p><p>> time/energy of the co=
mmittee, which is finite.<br>Yes you are right is it worth of effort.</p><p=
>I'll continue on this by making revision 2.<br>After few iteration it will=
be much easier to decide do we need this or not.<br>If not, we will have a=
nti-proposal :)<br>It is cheaper to burn my time than engage whole committe=
e.</p><p>> complexity of the language... And due to backwards compatibil=
ity ...<br>Agree.<br>I have idea of class interface extending that directly=
lead to bloat. <br>In some imaginare case after some time damage will be b=
eyond repair. Deprecation of that feature will be impossible.</p><p>Also I'=
d like to thanks to all by point me to important question for that I need t=
o provide more accurate answers:<br>1. Why should I use this?<br>2. Why sho=
uld I frequently use? More then I use friend now.<br>3. Benefits.<br>4. Exa=
mples with practical usage.</p><p>If I miss something fill free to add.</p>=
<p>Above we have abstract examples.</p><p>Her is text-book type:</p><p><fon=
t face=3D"courier new,monospace">class Fruit{<br> public:=
<br> int get_color(){ /* calculate color based on t=
ime and amount of sweet_core */ return time + sweet_core; } <br>  =
; int const& get_sweet_core()const{ return sweet_core; } <b=
r> void set_time( int const& t){ time =3D=
t; /* recalculate sweet_core*/ --sweet_core; }<br> =
int const& get_time( )const{ return time; }<br>protected:<br> &nb=
sp; int const& set_sweet_core( int & sc ){ sweet_core =3D sc; retur=
n sweet_core; }<br>private:<br> int time=3D100; <br> =
; int sweet_core=3D100;<br> friend Maggot >=
;> set_sweet_core;<br>};</font></p><p><font face=3D"courier new,monospac=
e">class Maggot{<br>public:<br> void eat( Fruit & f ){ while( f.se=
t_sweet_core( f.get_sweet_core() - 1 ) ); }<br>};</font></p><p><font face=
=3D"courier new,monospace">Fruit f;<br>Maggot m;</font></p><p><font face=3D=
"courier new,monospace">std::thread t1( [&](){ m.eat( f ); } );<br>std:=
:thread t2( [&](){ while( 0 !=3D f.get_sweet_core() ) f.set_time( f.get=
_time()+1 ); } );</font></p><div><font face=3D"courier new,monospace">// ..=
.. .. ...</font></div><div><font face=3D"Courier New"><div><font face=
=3D"courier new,monospace">// ... ... ...</font></div></font></div><di=
v><br></div><div>There is a data race. Ignore it.</div><div><br></div>=
<div>Obviously <font face=3D"courier new,monospace">time</font> is not conc=
ern of <font face=3D"courier new,monospace">Maggot</font> but <font face=3D=
"courier new,monospace">set_</font><font face=3D"courier new,monospace">swe=
at_core</font> is.</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6_975007285.1427498008278--
------=_Part_5_977650526.1427498008278--
.