220 7780 <db51f1e1-682d-4dab-b549-599c3c7dde77@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Fixing the private method issue
Date: Sat, 16 Nov 2013 10:21:31 -0800 (PST)
Lines: 280
Approved: news@gmane.org
Message-ID: <db51f1e1-682d-4dab-b549-599c3c7dde77@isocpp.org>
References: <527a6d7d.ea42420a.1057.ffffdaad@mx.google.com>
 <CAA7U3HNPAhAmRXFv5H9Dz0eHf36oDPOcXHnNkntqQRnZFC+aHA@mail.gmail.com>
 <CAPBZbvwDTinn3N_WWw7Mr7DWVzSbigL-WnC2XpGuQQbtp7faQw@mail.gmail.com> <CAA7U3HP6pSkVaV0wc0rsRUFv9BbbVsPSfohCwyHTHsUc=VHgow@mail.gmail.com>
 <CAPBZbvzckSiY=hBJTKk4zBTQfpU4op4OGJ9FmYp-m4nL-7FaSw@mail.gmail.com>
 <7a8d898e-1884-49f7-b0c8-52af0813e6c4@isocpp.org>
 <6ed8056e-dbf9-427c-9aca-19af755b1801@isocpp.org>
 <8065ebf8-09e7-432d-b4bc-075ef8331a89@isocpp.org>
 <cd1d13ab-ad2d-4b99-a89c-de0fc28ed8e7@isocpp.org>
 <4b190126-e8a8-404c-94c5-aeb7e9589686@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_1032_9115913.1384626091663"
X-Trace: ger.gmane.org 1384626088 3782 80.91.229.3 (16 Nov 2013 18:21:28 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sat, 16 Nov 2013 18:21:28 +0000 (UTC)
Cc: fmatthew5876@gmail.com, fmatthew5876@gmail.com, fmatthew5876@gmail.com
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCRIRSPDTQIRBLHPT2KAKGQEPNTJQQA@isocpp.org Sat Nov 16 19:21:34 2013
Return-path: <std-proposals+bncBCRIRSPDTQIRBLHPT2KAKGQEPNTJQQA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-gg0-f197.google.com ([209.85.161.197])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCRIRSPDTQIRBLHPT2KAKGQEPNTJQQA@isocpp.org>)
	id 1VhkUw-0008LN-7Z
	for gclcip-std-proposals@m.gmane.org; Sat, 16 Nov 2013 19:21:34 +0100
Original-Received: by mail-gg0-f197.google.com with SMTP id e5sf7418007ggk.0
        for <gclcip-std-proposals@m.gmane.org>; Sat, 16 Nov 2013 10:21:33 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:x-original-sender:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=FpKykkcdglfjcEfQAjQZckiGgya/nb4fz4mtqd2b3J8=;
        b=Nk8kIp418C7mcM3p0kAQMGoNyJASOxR6ZsQOxgvLcN0IQttR9LeN3biaMpJLXD379q
         FelQddHHg5x6i8ZWFfygsaCMHCk57866OihcoU9NquKLv9pFvAzD/DzUZnRNht2t7Go/
         jDEQottg3N9KUCMMHmGX/EwtE9V0wiAdykX13YcGNG6eG5MrCLdc/1+MxHiACEwIsVc2
         LBSie815CZbdYGcS9X+SAJz4OIK3aIHHZ63FZoXbJUOdafqyXjuXZjnr+EXY7fJR/Qh4
         8TMRa4jykRzTHaQlwa01u/f1+g+Aa3zkGlYlweUmzQgkgTgbn9TbyKHWXJds5w3dCfe5
         8Vlg==
X-Gm-Message-State: ALoCoQnj/slykOK539ww0kdH8o7Df//NkMi6BAC/onJZJ8M4uxlcUXL7rs68atJ0NrTCUMU81cOe
X-Received: by 10.236.14.100 with SMTP id c64mr7539815yhc.38.1384626093366;
        Sat, 16 Nov 2013 10:21:33 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.128.138 with SMTP id no10ls2020296qeb.18.gmail; Sat, 16 Nov
 2013 10:21:32 -0800 (PST)
X-Received: by 10.49.61.202 with SMTP id s10mr10356qer.21.1384626092509;
        Sat, 16 Nov 2013 10:21:32 -0800 (PST)
In-Reply-To: <4b190126-e8a8-404c-94c5-aeb7e9589686@isocpp.org>
X-Original-Sender: bengt.gustafsson@beamways.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:7780
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/7780>

------=_Part_1032_9115913.1384626091663
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I think it has been stated before in this thread that methods called by=20
inline methods declared in the class head must be in the class head. This=
=20
should mean that only overloads visible at the point of definition of the=
=20
calling inline method's body should be considered whenever that method is=
=20
instantiated or inlined. In the example this would mean that getBar() could=
=20
never call the non-const version of getBarImpl().

Maybe this was what you meant, "fmatth"?


When it comes to extension methods vs. opening a class scope to implement=
=20
methods I think these should be two orthogonal features. I also suggest to=
=20
use another syntax than "class namespaec Foo" to reopening a class. Like=20
this:

Foo:: {
    // Implement methods declared in class head:
    void Foo(int) {}    // A ctor
    int GetPi() { return 3; }   // Some other method

    // Combination of both features adds an extension method without=20
stating Foo::
    explicit void ExtraMethod() { cout << "Extra" << endl; }
}

// A "regular" extension method.
explicit void Foo::AdditionalExtra()
{
}


It could also be considered to replace the explicit keyword with "private"=
=20
as it makes it clear that the method is private. The drawback could be that=
=20
it becomes a bit hard to explain that if you put "private" in front of a=20
method declared in the class head it is an error while if you do it in=20
front of another method signature it is ok. Anyway, I think I would=20
personally prefer "private":

private void Foo::AnotherExtension()
{
}

Another drawback could be that some would ask why public and protected are=
=20
not allowed in the same way...


Den fredagen den 15:e november 2013 kl. 14:30:47 UTC+1 skrev=20
fmatth...@gmail.com:
>
>
>
> On Thursday, November 14, 2013 8:59:16 AM UTC-5, mitc...@gmail.com wrote:
>>
>> On Thursday, November 14, 2013 2:26:42 PM UTC+1, fmatth...@gmail.comwrot=
e:
>> [SNIP]
>>
>>> We can write 2 competing proposals. Either one I'd be happy with to=20
>>> improve compile times and improve encapsulation by hiding more=20
>>> implementation details from the user.
>>>
>>
>> The original goal  / scope of my (would be) class-namespace proposal is=
=20
>> to allow writing the implementation of class members with a less verbose=
 /=20
>> more uniform (with regards to the declaration) syntax, shoehorning these=
=20
>> hidden-private members into it doesn't seem like a good idea to me any=
=20
>> more, so if anything solid comes out from this proposal, I'll address it=
 in=20
>> the class-namespace proposal, too, if appropriate, but I won't introduce=
=20
>> this feature there.
>> =20
>>
>>> =20
>>>
>>>>
>>>> One issue that crossed my mind when thinking about "breaking" an=20
>>>> existing class: it should not be possible to add a "hidden" private me=
mber=20
>>>> that adds an overload to an existing declared private member.  I don't=
 know=20
>>>> if there's a similar constraint elsewhere in the standard, or if it'd =
be=20
>>>> completely new...
>>>>
>>>
>>> I think its probably ok to do this. You can define overloads for normal=
=20
>>> functions anywhere. Why not private member functions. The only taboo in=
 my=20
>>> mind is breaking encapsulation, which is what would happen if we allowe=
d=20
>>> extension of public, protected, data members, and/or virtual.=20
>>>
>>
>> But you _can_ break encapsulation by introducing private overloads,=20
>> consider this example:
>>
>> class Foo {
>>    int bar_;
>>    // ...
>>    int getBarImpl() const;
>> public:
>>    int getBar() { return getBarImpl(); }
>> };
>>
>> // evil.cc:
>>
>> // non-const override of Foo::getBarImpl():
>> explicit int Foo::getBarImpl() { bar_ =3D 42;  /* direct access to priva=
te=20
>> member... */ }
>> Foo f;
>> f.getBar(); // calls our evil override getBarImpl()
>>
>> Actually I don't even think this hole will work as intended. Consider=20
> this example:
>
>
> http://gcc.godbolt.org/#%7B%22version%22%3A3%2C%22filterAsm%22%3A%7B%22la=
bels%22%3Atrue%2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue%7D%2C%2=
2compilers%22%3A%5B%7B%22source%22%3A%22%5Cn%5Cn%5Cnint%20foo(const%20int%2=
6%20i)%20%7B%5Cn%20%20return%201%3B%5Cn%7D%5Cn%5Cninline%20int%20bar()%20%7=
B%5Cn%20%20int%20x%20%3D%202%3B%5Cn%20%20return%20foo(x)%3B%5Cn%7D%5Cn%5Cnt=
emplate%20%3Ctypename%20T%3E%5Cninline%20int%20baz()%20%7B%5Cn%20%20T%20x%2=
0%3D%202%3B%5Cn%20%20return%20foo(x)%3B%5Cn%7D%5Cn%5Cnint%20foo(int%26%20i)=
%20%7B%5Cn%20%20return%203%3B%5Cn%7D%5Cn%5Cnint%20main()%20%7B%5Cn%20%20%2F=
%2Funcomment%20to%20see%20result%5Cn%20%20%2F%2Freturn%20bar()%3B%5Cn%20%20=
%2F%2Freturn%20baz%3Cint%3E()%3B%5Cn%20%20return%20baz%3Cconst%20int%3E()%3=
B%5Cn%7D%22%2C%22compiler%22%3A%22%2Fusr%2Fbin%2Fg%2B%2B-4.8%22%2C%22option=
s%22%3A%22-O3%20-march%3Dnative%20-std%3Dc%2B%2B11%20%22%7D%5D%7D
> =20
>

--=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_1032_9115913.1384626091663
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I think it has been stated before in this thread that meth=
ods called by inline methods declared in the class head must be in the clas=
s head. This should mean that only overloads visible at the point of defini=
tion of the calling inline method's body should be considered whenever that=
 method is instantiated or inlined. In the example this would mean that get=
Bar() could never call the non-const version of getBarImpl().<div><br></div=
><div>Maybe this was what you meant, "fmatth"?</div><div><br></div><div><br=
></div><div>When it comes to extension methods vs. opening a class scope to=
 implement methods I think these should be two orthogonal features. I also =
suggest to use another syntax than "class namespaec Foo" to reopening a cla=
ss. Like this:</div><div><br></div><div>Foo:: {</div><div>&nbsp; &nbsp; // =
Implement methods declared in class head:</div><div>&nbsp; &nbsp; void Foo(=
int) {} &nbsp; &nbsp;// A ctor</div><div>&nbsp; &nbsp; int GetPi() { return=
 3; } &nbsp; // Some other method</div><div><br></div><div>&nbsp; &nbsp; //=
 Combination of both features adds an extension method without stating Foo:=
:</div><div>&nbsp; &nbsp; explicit void ExtraMethod() { cout &lt;&lt; "Extr=
a" &lt;&lt; endl; }</div><div>}</div><div><br></div><div>// A "regular" ext=
ension method.</div><div>explicit void Foo::AdditionalExtra()</div><div>{</=
div><div>}</div><div><br></div><div><br></div><div>It could also be conside=
red to replace the explicit keyword with "private" as it makes it clear tha=
t the method is private. The drawback could be that it becomes a bit hard t=
o explain that if you put "private" in front of a method declared in the cl=
ass head it is an error while if you do it in front of another method signa=
ture it is ok. Anyway, I think I would personally prefer "private":</div><d=
iv><br></div><div>private void Foo::AnotherExtension()</div><div>{</div><di=
v>}<br><div><br></div><div>Another drawback could be that some would ask wh=
y public and protected are not allowed in the same way...</div><div><br><br=
>Den fredagen den 15:e november 2013 kl. 14:30:47 UTC+1 skrev fmatth...@gma=
il.com:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><b=
r>On Thursday, November 14, 2013 8:59:16 AM UTC-5, <a>mitc...@gmail.com</a>=
 wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Thursday=
, November 14, 2013 2:26:42 PM UTC+1, <a>fmatth...@gmail.com</a> wrote:<div=
><span style=3D"font-size:13px">[SNIP]</span><br></div><div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc=
 solid;padding-left:1ex"><div dir=3D"ltr"><div>We can write 2 competing pro=
posals. Either one I'd be happy with to improve compile times and improve e=
ncapsulation by hiding more implementation details from the user.</div><div=
></div></div></blockquote><div><br></div><div>The original goal &nbsp;/ sco=
pe of my (would be) class-namespace proposal is to allow writing the implem=
entation of class members with a less verbose / more uniform (with regards =
to the declaration) syntax, shoehorning these hidden-private members into i=
t doesn't seem like a good idea to me any more, so if anything solid comes =
out from this proposal, I'll address it in the class-namespace proposal, to=
o, if appropriate, but I won't introduce this feature there.</div><div>&nbs=
p;</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>&nbsp=
;</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><br></=
div><div>One issue that crossed my mind when thinking about "breaking" an e=
xisting class: it should not be possible to add a "hidden" private member t=
hat adds an overload to an existing declared private member. &nbsp;I don't =
know if there's a similar constraint elsewhere in the standard, or if it'd =
be completely new...</div></div></blockquote><div><br></div><div>I think it=
s probably ok to do this. You can define overloads for normal functions any=
where. Why not private member functions. The only taboo in my mind is break=
ing encapsulation, which is what would happen if we allowed extension of pu=
blic, protected, data members, and/or virtual.&nbsp;</div></div></blockquot=
e><div><br></div><div>But you _can_ break encapsulation by introducing priv=
ate overloads, consider this example:</div><div><br></div><div>class Foo {<=
/div><div>&nbsp; &nbsp;int bar_;</div><div>&nbsp; &nbsp;// ...</div><div>&n=
bsp; &nbsp;int getBarImpl() const;</div><div>public:</div><div>&nbsp; &nbsp=
;int getBar() { return getBarImpl(); }</div><div>};</div><div><br></div><di=
v>// evil.cc:</div><div><br></div><div>// non-const override of Foo::getBar=
Impl():</div><div>explicit int Foo::getBarImpl() { bar_ =3D 42; &nbsp;/* di=
rect access to private member... */ }</div></div><div>Foo f;</div><div>f.ge=
tBar(); // calls our evil override getBarImpl()</div><div><br></div></div><=
/blockquote><div>Actually I don't even think this hole will work as intende=
d. Consider this example:</div><div><br></div><div><a href=3D"http://gcc.go=
dbolt.org/#%7B%22version%22%3A3%2C%22filterAsm%22%3A%7B%22labels%22%3Atrue%=
2C%22directives%22%3Atrue%2C%22commentOnly%22%3Atrue%7D%2C%22compilers%22%3=
A%5B%7B%22source%22%3A%22%5Cn%5Cn%5Cnint%20foo(const%20int%26%20i)%20%7B%5C=
n%20%20return%201%3B%5Cn%7D%5Cn%5Cninline%20int%20bar()%20%7B%5Cn%20%20int%=
20x%20%3D%202%3B%5Cn%20%20return%20foo(x)%3B%5Cn%7D%5Cn%5Cntemplate%20%3Cty=
pename%20T%3E%5Cninline%20int%20baz()%20%7B%5Cn%20%20T%20x%20%3D%202%3B%5Cn=
%20%20return%20foo(x)%3B%5Cn%7D%5Cn%5Cnint%20foo(int%26%20i)%20%7B%5Cn%20%2=
0return%203%3B%5Cn%7D%5Cn%5Cnint%20main()%20%7B%5Cn%20%20%2F%2Funcomment%20=
to%20see%20result%5Cn%20%20%2F%2Freturn%20bar()%3B%5Cn%20%20%2F%2Freturn%20=
baz%3Cint%3E()%3B%5Cn%20%20return%20baz%3Cconst%20int%3E()%3B%5Cn%7D%22%2C%=
22compiler%22%3A%22%2Fusr%2Fbin%2Fg%2B%2B-4.8%22%2C%22options%22%3A%22-O3%2=
0-march%3Dnative%20-std%3Dc%2B%2B11%20%22%7D%5D%7D" style=3D"font-size:13px=
" target=3D"_blank">http://gcc.godbolt.org/#%7B%<wbr>22version%22%3A3%2C%<w=
br>22filterAsm%22%3A%7B%22labels%<wbr>22%3Atrue%2C%22directives%22%<wbr>3At=
rue%2C%22commentOnly%22%<wbr>3Atrue%7D%2C%22compilers%22%<wbr>3A%5B%7B%22so=
urce%22%3A%22%<wbr>5Cn%5Cn%5Cnint%20foo(const%<wbr>20int%26%20i)%20%7B%5Cn%=
20%<wbr>20return%201%3B%5Cn%7D%5Cn%<wbr>5Cninline%20int%20bar()%20%7B%<wbr>=
5Cn%20%20int%20x%20%3D%202%3B%<wbr>5Cn%20%20return%20foo(x)%3B%<wbr>5Cn%7D%=
5Cn%5Cntemplate%20%<wbr>3Ctypename%20T%3E%5Cninline%<wbr>20int%20baz()%20%7=
B%5Cn%20%<wbr>20T%20x%20%3D%202%3B%5Cn%20%<wbr>20return%20foo(x)%3B%5Cn%7D%=
<wbr>5Cn%5Cnint%20foo(int%26%20i)%<wbr>20%7B%5Cn%20%20return%203%3B%<wbr>5C=
n%7D%5Cn%5Cnint%20main()%20%<wbr>7B%5Cn%20%20%2F%2Funcomment%<wbr>20to%20se=
e%20result%5Cn%20%20%<wbr>2F%2Freturn%20bar()%3B%5Cn%20%<wbr>20%2F%2Freturn=
%20baz%3Cint%3E(<wbr>)%3B%5Cn%20%20return%20baz%<wbr>3Cconst%20int%3E()%3B%=
5Cn%7D%<wbr>22%2C%22compiler%22%3A%22%<wbr>2Fusr%2Fbin%2Fg%2B%2B-4.8%22%<wb=
r>2C%22options%22%3A%22-O3%20-<wbr>march%3Dnative%20-std%3Dc%2B%<wbr>2B11%2=
0%22%7D%5D%7D</a>&nbsp;</div></div></blockquote></div></div></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/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1032_9115913.1384626091663--

.
