220 35284 <ef837718-0421-4780-948c-cc0c897cbcf8@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Overriding virtual functions of member class
Date: Mon, 6 Nov 2017 14:22:45 -0800 (PST)
Lines: 597
Approved: news@gmane.org
Message-ID: <ef837718-0421-4780-948c-cc0c897cbcf8@isocpp.org>
References: <26216c34-9ff6-435b-8da5-9b21460fee1c@isocpp.org>
 <48759c93-8f08-458e-ac0b-ea283b75faa1@isocpp.org> <4517d88c-2eb1-455a-b9c3-22af9d698ccd@isocpp.org>
 <2d810f36-74c5-4644-8eeb-f81db4e8687e@isocpp.org> <8383bc2f-638b-4519-ac20-8cfbfc9708d5@isocpp.org>
 <389229bd-7f50-4efa-b6c9-177df26bcd0a@isocpp.org> <5b06f168-cde4-45a9-8614-6025c8b16e85@isocpp.org>
 <6c6eec8c-5585-4cce-9517-5012ea20bac5@isocpp.org> <07032e79-d653-4ea3-84df-b405919ce51c@isocpp.org>
 <6855eee9-fec7-4d5b-86b1-1c42038e08d6@isocpp.org> <CAMD6iD8FyZu1+cq9tCDZY5e5qHMsAxp_7RCvnC7o1DzLC5g4Hg@mail.gmail.com>
 <b074840f-21a9-49e2-a664-e36c2164440e@isocpp.org> <CAMD6iD-ZPTfiKRRWJaUj7Sn8ZRh4r=P9drUBZ5msgn1DiMDpnw@mail.gmail.com>
 <CAMD6iD909cOvn9B7HSp4TZuip1Lq1TFVQEEkto5gV3aLpz8z-Q@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_13681_1943369652.1510006965196"
X-Trace: blaine.gmane.org 1510006968 7291 195.159.176.226 (6 Nov 2017 22:22:48 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 6 Nov 2017 22:22:48 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCRIRSPDTQIRBNWBQPIAKGQE4ZO25ZQ@isocpp.org Mon Nov 06 23:22:41 2017
Return-path: <std-proposals+bncBCRIRSPDTQIRBNWBQPIAKGQE4ZO25ZQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ua0-f199.google.com ([209.85.217.199])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCRIRSPDTQIRBNWBQPIAKGQE4ZO25ZQ@isocpp.org>)
	id 1eBpmy-0001f3-NV
	for gclcip-std-proposals@m.gmane.org; Mon, 06 Nov 2017 23:22:41 +0100
Original-Received: by mail-ua0-f199.google.com with SMTP id e46sf7096692uaa.6
        for <gclcip-std-proposals@m.gmane.org>; Mon, 06 Nov 2017 14:22:48 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to: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;
        bh=ZBukf9i2z80Gw04+jOc5/kjkmEzL1yLhhJmB4nyplC8=;
        b=kzdVswSWGWU2q013XHpV8aRCwjVOKcZxqfgy/ewV/1s3fn03Egw85DuN82GjgZcE9l
         5pkwQOvPPq1iETllZWIoCjCOwFv0od6jlTwHpAGwYzmjU1uyjWksSePhXA6bKleYWDiF
         dKnd2xAf/MWFPSfVBJH92HUS7iCasgXRt3dkEF9+TarQnj5hl77+jPhl+fWfE3GONeZb
         HGddSub9ex5HJgfQQeFUwdigCVneErIBdebhdsdhdJxb4Qyt4xt9YHrteVzGcRSx/Qgh
         /89xhFGBaChz9kuSstXm8BpKqsGp1KKd94yt3IDEe1vH3AMPS4i6Bnz4vB7+DYo3rQ9V
         1Qeg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=ZBukf9i2z80Gw04+jOc5/kjkmEzL1yLhhJmB4nyplC8=;
        b=js0vcEI228QAPS7qPArslTjq9r5c26/iZzwywlDKcoNQXOt7ppUToQkH2IK27wwX+u
         2d18VL6KEp0H1bF4d5bKmvt9rhNk4aByAHgasLwKkqBCwYBXADcw+jDxNVNu5RvCNXmU
         Y3uo7jJ96r3AJmLsPg1nv/m5m3W3+IIttjHZrjDqLwVz3fxrgHW+JLMGZ3D/Jdu4xure
         WxBCXvExYIxf75Comc2qAhWQgdvyWoWSLwnkbr0WGQH+qQrCRiWsla0Tx8YzaoXncShB
         BNFJZOYsy6XxfGuUTsZVie3VQ0UTq2RFT5r+96xqqmndRCg/+ihvz9oxYNO3cHLCen2a
         RI1g==
X-Gm-Message-State: AMCzsaXupI9hg7HyKr/UqOcypakljh6+XZ8TWiYDCWg1um/Js6zuj3it
	B46PyFhyVMfjt0wgf5+UUjXYlw==
X-Google-Smtp-Source: ABhQp+R3OHDWqVsEqNRA86xLAo7F+HQu6nmUBJxKioPGY1jtHqbi4d9x8TPACD0Yre2H+UThRfKvXA==
X-Received: by 10.176.71.81 with SMTP id i17mr9810992uac.23.1510006967840;
        Mon, 06 Nov 2017 14:22:47 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.151.69 with SMTP id z66ls3497393vkd.16.gmail; Mon, 06 Nov
 2017 14:22:46 -0800 (PST)
X-Received: by 10.31.201.198 with SMTP id z189mr1419263vkf.0.1510006965872;
        Mon, 06 Nov 2017 14:22:45 -0800 (PST)
In-Reply-To: <CAMD6iD909cOvn9B7HSp4TZuip1Lq1TFVQEEkto5gV3aLpz8z-Q@mail.gmail.com>
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: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:35284
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/35284>

------=_Part_13681_1943369652.1510006965196
Content-Type: multipart/alternative; 
	boundary="----=_Part_13682_778727460.1510006965197"

------=_Part_13682_778727460.1510006965197
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

I agree with the intention of this proposal: To simplify overriding methods=
=20
in subobjects without having to resort to an extraneous pointer to the=20
outer object, UB offsetof tricks or using mulitple inheritance when not=20
actually implementing an is-a relationship. However, as has been noted by=
=20
many in the ongoing discussion, the idea of _not_ viewing this as=20
subclassing seems very scary to me. I'm pretty sure that an idea which=20
changes the implementation of any virtual method will have to have a typeid=
=20
of its own to be acceptible. Given that it has to have a vtable anyway this=
=20
is going to be relatively cheap to add the type_info instance.

The important part of the proposal is that we need a way to define that the=
=20
subobject (m_a in the example) can reach the containing object's members=20
and methods using the compiler's knowledge of the relative position of them=
=20
compared to the this of the subobject. This looks like a limited form of=20
inner class. Or maybe I should say a restricted form. So what we need are=
=20
two things: a) to actually restrict the declaration so that we can't have=
=20
more than one object of this new class per containing object (these would=
=20
by necessity have a different offset from their thises to the members of=20
the containing object) and b) a way to justify that the surrounding=20
object's members can be accessed from the nested instance.

The original proposal handles b) by viewing the implementation as being a=
=20
method of the outer class rather than the subobject. This is a bit awkward=
=20
as it does not allow access to the members of the subobject without=20
prepending their names with the subobject name. And actually, what is=20
implemented seeing is a hidden forwarding method in the subobject vtable=20
which adjusts the this pointer and then calls the actual implemented method=
=20
which is a regular non-virtual method in the outer object. The a) objective=
=20
is achieved by not mentioning any subclassing so there is no possibility to=
=20
create another instance of the subobject's class outside the outer object.

This means that the main requisites are fulfilled. The remaning problem is,=
=20
in my mind, clarity. There is no mentioning that the A m_a; declaration is=
=20
not just a plain old A close to its declaration, the method overrides can=
=20
be anywhere in the class head. The main issue I have with this is that the=
=20
method overrides are not written inside the class head of the class being=
=20
created. This creates a lot of unnecessary confusion. The solution close at=
=20
hand seems to be an anonymous class declaration:

 =20
class Client {
    class : public Timer {
        void timerExpired() override {
            Client::m_client_manager.clientDisconnected(*Client::this);
        }
    } m_timer;  // As the subclass has no name we know there will be no=20
more instances.
};



The weak part of this suggestion is probably the access of outer class=20
members (including this) using a class scope prefix. This seems like=20
mutliple inheritance except that you can't inherit from the outer class in=
=20
the inner class' declaration as it is incomplete by necessity. It may also=
=20
seem like this syntax would be usable in any nested class, which of course=
=20
it can't be. Unless... a way to achieve general inner class functionality=
=20
is to allow inheriting from the surrounding class using indirect=20
inheritance. This case would then become a special case of that feature and=
=20
the problem of how to access the outer object is just moved to the cast=20
operator to the outer class. Furthermore a new set of boilerplate is=20
introduced which reduces the appeal of the functionality. One obscure way=
=20
to create a syntax for the this pointer of the containing class is to=20
redefine this from being a pointer to being an array. Thanks to C++ array=
=20
to pointer conversion this would still work as usual but would now have an=
=20
operator[] to reach the outer class.

Combining these features and indicating indirect inheritance with a=20
combination of virtual inheritance and a cast operator to the same class we=
=20
get:

class Client {
     class : Timer, virtual Client {   // Reversed multiple inheritance=20
motivates accessing Client members directly.
          operator Client&() { return this[1]; }  // Mysterious=20
boilerplate...
          void timerExpired() override {
               m_client_manager.clientDisconnected(*this);
          }
     } m_a;
     ClientManager& m_client_manager;
};


Note that this[1] does not mean to access the second base class, but to=20
access the containing object's this pointer. this[1] is only valid syntax=
=20
inside code of an unnamed nested class where the offset to the outer object=
=20
can be deduced by the compiler. Note also that the *this parameter to=20
clientDisconnected does not have to be written this[1] as the cast operator=
=20
to baseclass will kick in anyway (presuming that clientDisconnected takes a=
=20
Client& as parameter which I assume it does.

The virtual inheritance of Client is not limited to the case but is part of=
=20
a general inner class idea which piggybacks on a general indirect=20
inheritance idea where indirect inheritance is a generalization of the=20
current virtual inheritance concept allowing a cast operator to provide the=
=20
actual address of the base subobject rather than only the current mechanism=
..

So, by this I try to kill not only two but three birds with one stone! We=
=20
will get both indirect inheritance (i.e. the better operator.()), inner=20
classes (full Java functionality) and the OP feature with just a few small=
=20
changes:

- virtual inheritance can be generalized to indirect inheritance by having=
=20
a cast operator to the class inherited from in parallel.
- virtual inheritance of an outer class is allowed.
- this[1] can be used to access the containing object of a nested instance=
=20
if the class is anonymous and there is only one instance in the declaration=
..

Also, as a final coda note that the third of these features is enough to=20
handle the OP case:

class Client {
     class : Timer {   // Anonymous class inheriting from Timer
          void timerExpired() override {
               this[1].m_client_manager.clientDisconnected(this[1]);   //=
=20
this[1] defined.
          }
     } m_a;  // Only one by value instance.

     ClientManager& m_client_manager;
};



Den m=C3=A5ndag 6 november 2017 kl. 06:29:27 UTC+1 skrev Ren Industries:
>
> Yeah, std::function without using the part that requires allocation.
>
> On Nov 4, 2017 3:26 PM, <amb...@gmail.com <javascript:>> wrote:
>
>
>
> On Saturday, November 4, 2017 at 8:23:03 PM UTC+1, Ren Industries wrote:
>>
>> How about just using std::function or boost::signal or one of the myriad=
=20
>> of ways to implement delegates, rather than trying to change an essentia=
l=20
>> part of how the object model works?
>>
>
> In my original post, I explain the problems with std::function:
> - Boilerplate needed to bind the callback (especially the=20
> std::placeholder's).
> - std::bind/std::function is not noexcept and may require dynamic memory=
=20
> allocation, this is unacceptable for certain embedded systems.
> - Less memory efficient, each callback necessarily contributes at least 2=
=20
> words to the total size of the containing object (a function pointer and =
an=20
> instance pointer). But with virtual functions, all virtual functions in o=
ne=20
> subobject together contribute only 1 word (the vtable pointer). Yes I kno=
w=20
> the program memory (.text section) overhead is different.
>
> I am pretty confident there is no existing solution which addresses all o=
f=20
> these problems.
>
> --=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> To view this discussion on the web visit=20
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b074840f-21a=
9-49e2-a664-e36c2164440e%40isocpp.org=20
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b074840f-21=
a9-49e2-a664-e36c2164440e%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
>
>

--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ef837718-0421-4780-948c-cc0c897cbcf8%40isocpp.or=
g.

------=_Part_13682_778727460.1510006965197
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I agree with the intention of this proposal: To simplify o=
verriding methods in subobjects without having to resort to an extraneous p=
ointer to the outer object, UB offsetof tricks or using mulitple inheritanc=
e when not actually implementing an is-a relationship. However, as has been=
 noted by many in the ongoing discussion, the idea of _not_ viewing this as=
 subclassing seems very scary to me. I&#39;m pretty sure that an idea which=
 changes the implementation of any virtual method will have to have a typei=
d of its own to be acceptible. Given that it has to have a vtable anyway th=
is is going to be relatively cheap to add the type_info instance.<div><br><=
/div><div>The important part of the proposal is that we need a way to defin=
e that the subobject (m_a in the example) can reach the containing object&#=
39;s members and methods using the compiler&#39;s knowledge of the relative=
 position of them compared to the this of the subobject. This looks like a =
limited form of inner class. Or maybe I should say a restricted form. So wh=
at we need are two things: a) to actually restrict the declaration so that =
we can&#39;t have more than one object of this new class per containing obj=
ect (these would by necessity have a different offset from their thises to =
the members of the containing object) and b) a way to justify that the surr=
ounding object&#39;s members can be accessed from the nested instance.</div=
><div><br></div><div>The original proposal handles b) by viewing the implem=
entation as being a method of the outer class rather than the subobject. Th=
is is a bit awkward as it does not allow access to the members of the subob=
ject without prepending their names with the subobject name. And actually, =
what is implemented seeing is a hidden forwarding method in the subobject v=
table which adjusts the this pointer and then calls the actual implemented =
method which is a regular non-virtual method in the outer object. The a) ob=
jective is achieved by not mentioning any subclassing so there is no possib=
ility to create another instance of the subobject&#39;s class outside the o=
uter object.</div><div><br></div><div>This means that the main requisites a=
re fulfilled. The remaning problem is, in my mind, clarity. There is no men=
tioning that the A m_a; declaration is not just a plain old A close to its =
declaration, the method overrides can be anywhere in the class head. The ma=
in issue I have with this is that the method overrides are not written insi=
de the class head of the class being created. This creates a lot of unneces=
sary confusion. The solution close at hand seems to be an anonymous class d=
eclaration:</div><div><br></div><div>=C2=A0 </div><div class=3D"prettyprint=
" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187=
, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><co=
de class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Client</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">public</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">Timer</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> timerExpired</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">override</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Client</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">m_client_manager</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">clientDisconnected</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(*</span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Client</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">this</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> m_timer</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
=C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-prettify">// A=
s the subclass has no name we know there will be no more instances.</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></di=
v><div><br><br></div><div>The weak part of this suggestion is probably the =
access of outer class members (including this) using a class scope prefix. =
This seems like mutliple inheritance except that you can&#39;t inherit from=
 the outer class in the inner class&#39; declaration as it is incomplete by=
 necessity. It may also seem like this syntax would be usable in any nested=
 class, which of course it can&#39;t be. Unless... a way to achieve general=
 inner class functionality is to allow inheriting from the surrounding clas=
s using indirect inheritance. This case would then become a special case of=
 that feature and the problem of how to access the outer object is just mov=
ed to the cast operator to the outer class. Furthermore a new set of boiler=
plate is introduced which reduces the appeal of the functionality. One obsc=
ure way to create a syntax for the this pointer of the containing class is =
to redefine this from being a pointer to being an array. Thanks to C++ arra=
y to pointer conversion this would still work as usual but would now have a=
n operator[] to reach the outer class.</div><div><br></div><div>Combining t=
hese features and indicating indirect inheritance with a combination of vir=
tual inheritance and a cast operator to the same class we get:</div><div><b=
r></div><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,=
 250); border-color: rgb(187, 187, 187); border-style: solid; border-width:=
 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">clas=
s</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Client</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"sty=
led-by-prettify">Timer</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">virtua=
l</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">Client</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">// Reversed multiple inheritance motivates=
 accessing Client members directly.</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">operator</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Client</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">&amp;()</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">this=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">];</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> =C2=A0</span><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">// Mysterious boilerplate...</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> timerExpired</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">override</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0m_client_manager</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">clientDisconnected</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(*</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">this</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> m_a</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #606;" class=3D"=
styled-by-prettify">ClientManager</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> m_client_manager</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br><br></span></div></code></div><div><br>Note that this[1] does not me=
an to access the second base class, but to access the containing object&#39=
;s this pointer. this[1] is only valid syntax inside code of an unnamed nes=
ted class where the offset to the outer object can be deduced by the compil=
er. Note also that the *this parameter to clientDisconnected does not have =
to be written this[1] as the cast operator to baseclass will kick in anyway=
 (presuming that clientDisconnected takes a Client&amp; as parameter which =
I assume it does.</div><div><br></div><div>The virtual inheritance of Clien=
t is not limited to the case but is part of a general inner class idea whic=
h piggybacks on a general indirect inheritance idea where indirect inherita=
nce is a generalization of the current virtual inheritance concept allowing=
 a cast operator to provide the actual address of the base subobject rather=
 than only the current mechanism.</div><div><br></div><div>So, by this I tr=
y to kill not only two but three birds with one stone! We will get both ind=
irect inheritance (i.e. the better operator.()), inner classes (full Java f=
unctionality) and the OP feature with just a few small changes:</div><div><=
br></div><div>- virtual inheritance can be generalized to indirect inherita=
nce by having a cast operator to the class inherited from in parallel.</div=
><div>- virtual inheritance of an outer class is allowed.</div><div>- this[=
1] can be used to access the containing object of a nested instance if the =
class is anonymous and there is only one instance in the declaration.</div>=
<div><br></div><div>Also, as a final coda note that the third of these feat=
ures is enough to handle the OP case:</div><div><br></div><div><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace; background-color: =
rgb(250, 250, 250); color: rgb(0, 0, 136);">class</span><span class=3D"styl=
ed-by-prettify" style=3D"font-family: monospace; background-color: rgb(250,=
 250, 250); color: rgb(0, 0, 0);">=C2=A0</span><span class=3D"styled-by-pre=
ttify" style=3D"font-family: monospace; background-color: rgb(250, 250, 250=
); color: rgb(102, 0, 102);">Client</span><span class=3D"styled-by-prettify=
" style=3D"font-family: monospace; background-color: rgb(250, 250, 250); co=
lor: rgb(0, 0, 0);">=C2=A0</span><span class=3D"styled-by-prettify" style=
=3D"font-family: monospace; background-color: rgb(250, 250, 250); color: rg=
b(102, 102, 0);">{</span><span class=3D"styled-by-prettify" style=3D"font-f=
amily: monospace; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0)=
;"><br>=C2=A0 =C2=A0 =C2=A0</span><span class=3D"styled-by-prettify" style=
=3D"font-family: monospace; background-color: rgb(250, 250, 250); color: rg=
b(0, 0, 136);">class</span><span class=3D"styled-by-prettify" style=3D"font=
-family: monospace; background-color: rgb(250, 250, 250); color: rgb(0, 0, =
0);">=C2=A0</span><span class=3D"styled-by-prettify" style=3D"font-family: =
monospace; background-color: rgb(250, 250, 250); color: rgb(102, 102, 0);">=
:</span><span class=3D"styled-by-prettify" style=3D"font-family: monospace;=
 background-color: rgb(250, 250, 250); color: rgb(0, 0, 0);">=C2=A0</span><=
span class=3D"styled-by-prettify" style=3D"font-family: monospace; backgrou=
nd-color: rgb(250, 250, 250); color: rgb(102, 0, 102);">Timer</span><span c=
lass=3D"styled-by-prettify" style=3D"font-family: monospace; background-col=
or: rgb(250, 250, 250); color: rgb(0, 0, 0);">=C2=A0</span><span class=3D"s=
tyled-by-prettify" style=3D"font-family: monospace; background-color: rgb(2=
50, 250, 250); color: rgb(102, 102, 0);">{=C2=A0 =C2=A0// Anonymous class i=
nheriting from Timer</span><span class=3D"styled-by-prettify" style=3D"font=
-family: monospace; background-color: rgb(250, 250, 250); color: rgb(0, 0, =
0);"><br></span><span class=3D"styled-by-prettify" style=3D"font-family: mo=
nospace; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0);">=C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0=C2=A0</span><span class=3D"styled-by-prettify"=
 style=3D"font-family: monospace; background-color: rgb(250, 250, 250); col=
or: rgb(0, 0, 136);">void</span><span class=3D"styled-by-prettify" style=3D=
"font-family: monospace; background-color: rgb(250, 250, 250); color: rgb(0=
, 0, 0);">=C2=A0timerExpired</span><span class=3D"styled-by-prettify" style=
=3D"font-family: monospace; background-color: rgb(250, 250, 250); color: rg=
b(102, 102, 0);">()</span><span class=3D"styled-by-prettify" style=3D"font-=
family: monospace; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0=
);">=C2=A0</span><span class=3D"styled-by-prettify" style=3D"font-family: m=
onospace; background-color: rgb(250, 250, 250); color: rgb(0, 0, 136);">ove=
rride</span><span class=3D"styled-by-prettify" style=3D"font-family: monosp=
ace; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0);">=C2=A0</sp=
an><span class=3D"styled-by-prettify" style=3D"font-family: monospace; back=
ground-color: rgb(250, 250, 250); color: rgb(102, 102, 0);">{</span><span c=
lass=3D"styled-by-prettify" style=3D"font-family: monospace; background-col=
or: rgb(250, 250, 250); color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0this[1].m_client_manager</span><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace; background-color: =
rgb(250, 250, 250); color: rgb(102, 102, 0);">.</span><span class=3D"styled=
-by-prettify" style=3D"font-family: monospace; background-color: rgb(250, 2=
50, 250); color: rgb(0, 0, 0);">clientDisconnected</span><span class=3D"sty=
led-by-prettify" style=3D"font-family: monospace; background-color: rgb(250=
, 250, 250); color: rgb(102, 102, 0);">(</span><span class=3D"styled-by-pre=
ttify" style=3D"font-family: monospace; background-color: rgb(250, 250, 250=
); color: rgb(0, 0, 136);">this[1]</span><span class=3D"styled-by-prettify"=
 style=3D"font-family: monospace; background-color: rgb(250, 250, 250); col=
or: rgb(102, 102, 0);">);=C2=A0 =C2=A0// this[1] defined.</span><span class=
=3D"styled-by-prettify" style=3D"font-family: monospace; background-color: =
rgb(250, 250, 250); color: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0=C2=A0</span><span class=3D"styled-by-prettify" style=3D"font-family:=
 monospace; background-color: rgb(250, 250, 250); color: rgb(102, 102, 0);"=
>}</span><span class=3D"styled-by-prettify" style=3D"font-family: monospace=
; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0);"><br>=C2=A0 =
=C2=A0 =C2=A0</span><span class=3D"styled-by-prettify" style=3D"font-family=
: monospace; background-color: rgb(250, 250, 250); color: rgb(102, 102, 0);=
">}</span><span class=3D"styled-by-prettify" style=3D"font-family: monospac=
e; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0);">=C2=A0m_a</s=
pan><span class=3D"styled-by-prettify" style=3D"font-family: monospace; bac=
kground-color: rgb(250, 250, 250); color: rgb(102, 102, 0);">;=C2=A0 // Onl=
y one by value instance.</span></div><div><span class=3D"styled-by-prettify=
" style=3D"font-family: monospace; background-color: rgb(250, 250, 250);"><=
font color=3D"#666600"><br></font><font color=3D"#000000">=C2=A0 =C2=A0 =C2=
=A0</font></span><span class=3D"styled-by-prettify" style=3D"font-family: m=
onospace; background-color: rgb(250, 250, 250); color: rgb(102, 0, 102);">C=
lientManager</span><span class=3D"styled-by-prettify" style=3D"font-family:=
 monospace; background-color: rgb(250, 250, 250); color: rgb(102, 102, 0);"=
>&amp;</span><span class=3D"styled-by-prettify" style=3D"font-family: monos=
pace; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0);">=C2=A0m_c=
lient_manager</span><span class=3D"styled-by-prettify" style=3D"font-family=
: monospace; background-color: rgb(250, 250, 250); color: rgb(102, 102, 0);=
">;</span><span class=3D"styled-by-prettify" style=3D"font-family: monospac=
e; background-color: rgb(250, 250, 250); color: rgb(0, 0, 0);"><br></span><=
span class=3D"styled-by-prettify" style=3D"font-family: monospace; backgrou=
nd-color: rgb(250, 250, 250); color: rgb(102, 102, 0);">};</span><span clas=
s=3D"styled-by-prettify" style=3D"font-family: monospace; background-color:=
 rgb(250, 250, 250); color: rgb(0, 0, 0);"><br></span></div><div><br></div>=
<div><br></div><div><br>Den m=C3=A5ndag 6 november 2017 kl. 06:29:27 UTC+1 =
skrev Ren Industries:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"auto">Yeah, std::function without using the part that requires allocati=
on.</div><div><br><div class=3D"gmail_quote">On Nov 4, 2017 3:26 PM,  &lt;<=
a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"1b-0NUxWB=
wAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;retu=
rn true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">amb...=
@gmail.com</a>&gt; wrote:<br type=3D"attribution"><blockquote style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div><br><br>On Saturday, November 4, 2017 at 8:23:03 PM UTC+1, Ren Indust=
ries wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto">How ab=
out just using std::function or boost::signal or one of the myriad of ways =
to implement delegates, rather than trying to change an essential part of h=
ow the object model works?</div></blockquote><div><br></div></div><div>In m=
y original post, I explain the problems with std::function:</div><div><div>=
<div>- Boilerplate needed to bind the callback (especially the std::placeho=
lder&#39;s).</div><div>- std::bind/std::function is not noexcept and may re=
quire dynamic memory allocation, this is unacceptable for certain embedded =
systems.</div><div>- Less memory efficient, each callback necessarily contr=
ibutes at least 2 words to the total size of the containing object (a funct=
ion pointer and an instance pointer). But with virtual functions, all virtu=
al functions in one subobject together contribute only 1 word (the vtable p=
ointer). Yes I know the program memory (.text section) overhead is differen=
t.</div></div><div><br></div></div><div>I am pretty confident there is no e=
xisting solution which addresses all of these problems.</div></div><div>

<p></p>

-- <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 <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
1b-0NUxWBwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&=
#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true=
;">std-proposal...@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"1b-0NUxWBwAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">std-pr...@isocpp.org</a>.<br></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b074840f-21a9-49e2-a664-e36c2164440e%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank" =
rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/b074840f-21a9-49e2-a664-e36c2164440e%40i=
socpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return true;" on=
click=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/b074840f-21a9-49e2-a664-e36c2164440e%40isocpp.org?utm_medium\x3=
demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.google.com=
/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/b074840f-21a9-49e2-<wbr>a664-=
e36c2164440e%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div>
</blockquote></div></div>

<p></p>

-- <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 <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ef837718-0421-4780-948c-cc0c897cbcf8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ef837718-0421-4780-948c-cc0c897cbcf8=
%40isocpp.org</a>.<br />

------=_Part_13682_778727460.1510006965197--

------=_Part_13681_1943369652.1510006965196--

.
