Topic: Re: [std-proposals] Re: Proposal: Class static pr
Author: David Krauss <potswa@gmail.com>
Date: Wed, 6 May 2015 15:23:02 +0800
Raw View
--Apple-Mail=_1D7AE3B9-A6B4-4D0A-87EA-CC865BA8F099
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9305=E2=80=9306, at 2:49 PM, Edward Catmur <ed@catmur.co.uk=
> wrote:
>=20
> The term "attribute" is [[already_taken]]. Call these what they are: virt=
ual static data members.=20
=E2=80=A6 which were discussed here within the last few weeks. See the thre=
ad =E2=80=9CVirtual constexpr fields,=E2=80=9D March 19-24.
> I would also suggest collecting some performance measurements to back up =
your argument (eg with a hand-rolled vtable implementation).
Artificial benchmarks are artificial. We know, without inventing anything, =
that virtual functions cost an indirect branch instruction whereas the prop=
osal reduces it to a load.
However, closest alternative from the machine=E2=80=99s perspective might n=
ot be a virtual function, but an ordinary nonstatic data member in the abst=
ract base class or a virtual base class.
More concrete motivation would require finding examples of various things t=
hat should be virtual static members but aren=E2=80=99t. Clang has fought a=
massive battle against RTTI complexity, it might be a fertile ground.
> You should also make it clear that you understand that the C++ standard d=
oes not mandate vtables as an implementation technique although of course i=
n practice every implementation uses them.=20
Vtables aren=E2=80=99t central to this sort of proposal. Virtual calls must=
somehow involve a function pointer somewhere, and the proposal is to repla=
ce those with arbitrary object storage.
> Would this mean that pointers to data members can now involve a vtable lo=
okup? Could that break ABI?=20
Good question, and I don=E2=80=99t think it was raised in the last thread.
Already PTMs can=E2=80=99t reach virtual bases or static members, so virtua=
l static members would also seem to be inapplicable.
> Is it really necessary that virtual static data members be const? Non-con=
st virtual static data members would have to be allocated outside the vtabl=
e itself, but access to them would still be considerably cheaper than a nul=
lary virtual method call. Note that also objects with run time initializati=
on would need to be allocated outside the vtable, even if they were const t=
hereafter.=20
I touched on this in the other discussion. You could always link a modifiab=
le global object to the vtable using a const[expr] pointer to it. The quest=
ion comes down to whether the implementation should be required to do this =
for you, when you request something that can=E2=80=99t be placed in the vta=
ble.
--=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=_1D7AE3B9-A6B4-4D0A-87EA-CC865BA8F099
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=9305=
=E2=80=9306, at 2:49 PM, Edward Catmur <<a href=3D"mailto:ed@catmur.co.u=
k" class=3D"">ed@catmur.co.uk</a>> wrote:</div><br class=3D"Apple-interc=
hange-newline"><div class=3D"">The term "attribute" is [[already_taken]]. C=
all these what they are: virtual static data members. <br class=3D""></div>=
</blockquote><div><br class=3D""></div><div>=E2=80=A6 which were discussed =
here within the last few weeks. See the thread =E2=80=9C<font face=3D"Helve=
tica Neue" class=3D"">Virtual constexpr fields,=E2=80=9D March 19-24.</font=
></div><br class=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">=
I would also suggest collecting some performance measurements to back up yo=
ur argument (eg with a hand-rolled vtable implementation). </div></blockquo=
te><div><br class=3D""></div><div>Artificial benchmarks are artificial. We =
know, without inventing anything, that virtual functions cost an indirect b=
ranch instruction whereas the proposal reduces it to a load.</div><div><br =
class=3D""></div><div>However, closest alternative from the machine=E2=80=
=99s perspective might not be a virtual function, but an ordinary nonstatic=
data member in the abstract base class or a virtual base class.</div><div>=
<br class=3D""></div><div>More concrete motivation would require finding ex=
amples of various things that should be virtual static members but aren=E2=
=80=99t. Clang has fought a massive battle against RTTI complexity, it migh=
t be a fertile ground.</div><br class=3D""><blockquote type=3D"cite" class=
=3D""><div class=3D"">You should also make it clear that you understand tha=
t the C++ standard does not mandate vtables as an implementation technique =
although of course in practice every implementation uses them. <br class=3D=
""></div></blockquote><div><br class=3D""></div><div>Vtables aren=E2=80=99t=
central to this sort of proposal. Virtual calls must somehow involve a fun=
ction pointer somewhere, and the proposal is to replace those with arbitrar=
y object storage.</div><br class=3D""><blockquote type=3D"cite" class=3D"">=
<div class=3D"">Would this mean that pointers to data members can now invol=
ve a vtable lookup? Could that break ABI? <br class=3D""></div></blockquote=
><div><br class=3D""></div><div>Good question, and I don=E2=80=99t think it=
was raised in the last thread.</div><div><br class=3D""></div><div>Already=
PTMs can=E2=80=99t reach virtual bases or static members, so virtual stati=
c members would also seem to be inapplicable.</div><div><br class=3D""></di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">Is it really necessa=
ry that virtual static data members be const? Non-const virtual static data=
members would have to be allocated outside the vtable itself, but access t=
o them would still be considerably cheaper than a nullary virtual method ca=
ll. Note that also objects with run time initialization would need to be al=
located outside the vtable, even if they were const thereafter. <br class=
=3D""></div></blockquote></div><br class=3D""><div class=3D"">I touched on =
this in the other discussion. You could always link a modifiable global obj=
ect to the vtable using a const[expr] pointer to it. The question comes dow=
n to whether the implementation should be required to do this for you, when=
you request something that can=E2=80=99t be placed in the vtable.</div></b=
ody></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=_1D7AE3B9-A6B4-4D0A-87EA-CC865BA8F099--
.
Author: David Krauss <potswa@gmail.com>
Date: Wed, 6 May 2015 15:28:53 +0800
Raw View
--Apple-Mail=_E23E608D-0877-4461-999B-22EF6029959D
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9305=E2=80=9306, at 3:23 PM, David Krauss <potswa@gmail.com=
> wrote:
>=20
> I touched on this in the other discussion. You could always link a modifi=
able global object to the vtable using a const[expr] pointer to it. The que=
stion comes down to whether the implementation should be required to do thi=
s for you, when you request something that can=E2=80=99t be placed in the v=
table.
=E2=80=A6 Ah, it=E2=80=99s a bad idea. Doing it automatically would make th=
e storage of a static virtual member of literal type depend on whether its =
initializer is a constant expression. That would make library ABIs too brit=
tle.
The only alternatives are:
1. Allow only literal types with constant initializers,
2. Require constant initializers but only for literal types,
3. Store everything outside the vtable.
#2 is esoteric and #3 defeats the point of the proposal, so we=E2=80=99re s=
tuck with #1.
--=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=_E23E608D-0877-4461-999B-22EF6029959D
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=9305=
=E2=80=9306, at 3:23 PM, David Krauss <<a href=3D"mailto:potswa@gmail.co=
m" class=3D"">potswa@gmail.com</a>> wrote:</div><br class=3D"Apple-inter=
change-newline"><div class=3D""><span style=3D"font-family: Helvetica; font=
-size: 12px; font-style: normal; font-variant: normal; font-weight: normal;=
letter-spacing: normal; line-height: normal; orphans: auto; text-align: st=
art; text-indent: 0px; text-transform: none; white-space: normal; widows: a=
uto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; displa=
y: inline !important;" class=3D"">I touched on this in the other discussion=
.. You could always link a modifiable global object to the vtable using a co=
nst[expr] pointer to it. The question comes down to whether the implementat=
ion should be required to do this for you, when you request something that =
can=E2=80=99t be placed in the vtable.</span></div></blockquote></div><br c=
lass=3D""><div class=3D"">=E2=80=A6 Ah, it=E2=80=99s a bad idea. Doing it a=
utomatically would make the storage of a static virtual member of literal t=
ype depend on whether its initializer is a constant expression. That would =
make library ABIs too brittle.</div><div class=3D""><br class=3D""></div><d=
iv class=3D"">The only alternatives are:</div><div class=3D""><br class=3D"=
"></div><div class=3D"">1. Allow only literal types with constant initializ=
ers,</div><div class=3D"">2. Require constant initializers but only for lit=
eral types,</div><div class=3D"">3. Store everything outside the vtable.</d=
iv><div class=3D""><br class=3D""></div><div class=3D"">#2 is esoteric and =
#3 defeats the point of the proposal, so we=E2=80=99re stuck with #1.</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=_E23E608D-0877-4461-999B-22EF6029959D--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Wed, 06 May 2015 08:08:50 -0700
Raw View
On Tuesday 05 May 2015 15:21:38 John Yates wrote:
> > Lastly, don't call them "properties". It gives the wrong impression;
> > people might start thinking of C# properties.
>
> Do you think that "class attribute" is a better, less misleading phrase?
> (I have tentatively updated the proposal replacing property with
> attribute.)
It's a "virtual static", the first of its kind.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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: Brent Friedman <fourthgeek@gmail.com>
Date: Wed, 6 May 2015 11:34:40 -0500
Raw View
--047d7b5db4aa2cb78a05156c5f5f
Content-Type: text/plain; charset=UTF-8
I wrote up a skeletal proposal of this a few years ago and it has been
brought up by others since then. Here is a link to what I wrote at the time:
http://s000.tinyupload.com/?file_id=24402666636951570023
The biggest concern that I heard was that on some platforms vtables are
stored in read-only memory so putting non-const data in the vtable would
break that / complicate implementation.
I'd be happy to collaborate on building a proper proposal.
On Wed, May 6, 2015 at 10:08 AM, Thiago Macieira <thiago@macieira.org>
wrote:
> On Tuesday 05 May 2015 15:21:38 John Yates wrote:
> > > Lastly, don't call them "properties". It gives the wrong impression;
> > > people might start thinking of C# properties.
> >
> > Do you think that "class attribute" is a better, less misleading phrase?
> > (I have tentatively updated the proposal replacing property with
> > attribute.)
>
> It's a "virtual static", the first of its kind.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel Open Source Technology Center
> PGP/GPG: 0x6EF45358; fingerprint:
> E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
>
> --
>
> ---
> 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/.
--047d7b5db4aa2cb78a05156c5f5f
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I wrote up a skeletal proposal of this a few years ago and=
it has been brought up by others since then. Here is a link to what I wrot=
e at the time:<div><br><div><a href=3D"http://s000.tinyupload.com/?file_id=
=3D24402666636951570023">http://s000.tinyupload.com/?file_id=3D244026666369=
51570023</a><br></div><div><br></div><div>The biggest concern that I heard =
was that on some platforms vtables are stored in read-only memory so puttin=
g non-const data in the vtable would break that / complicate implementation=
..</div><div><br></div><div>I'd be happy to collaborate on building a pr=
oper proposal.</div></div><div><br></div></div><div class=3D"gmail_extra"><=
br><div class=3D"gmail_quote">On Wed, May 6, 2015 at 10:08 AM, Thiago Macie=
ira <span dir=3D"ltr"><<a href=3D"mailto:thiago@macieira.org" target=3D"=
_blank">thiago@macieira.org</a>></span> wrote:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><span class=3D"">On Tuesday 05 May 2015 15:21:38 John Yates wrote:=
<br>
> > Lastly, don't call them "properties". It gives the =
wrong impression;<br>
> > people might start thinking of C# properties.<br>
><br>
> Do you think that "class attribute" is a better, less mislea=
ding phrase?<br>
>=C2=A0 (I have tentatively updated the proposal replacing property with=
<br>
> attribute.)<br>
<br>
</span>It's a "virtual static", the first of its kind.<br>
<span class=3D"HOEnZb"><font color=3D"#888888"><br>
--<br>
Thiago Macieira - thiago (AT) <a href=3D"http://macieira.info" target=3D"_b=
lank">macieira.info</a> - thiago (AT) <a href=3D"http://kde.org" target=3D"=
_blank">kde.org</a><br>
=C2=A0 =C2=A0Software Architect - Intel Open Source Technology Center<br>
=C2=A0 =C2=A0 =C2=A0 PGP/GPG: 0x6EF45358; fingerprint:<br>
=C2=A0 =C2=A0 =C2=A0 E067 918B B660 DBD1 105C=C2=A0 966C 33F5 F005 6EF4 535=
8<br>
</font></span><div class=3D"HOEnZb"><div class=3D"h5"><br>
--<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%2Bunsubscribe@isocpp.org">std-propo=
sals+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/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></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 />
--047d7b5db4aa2cb78a05156c5f5f--
.
Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Thu, 7 May 2015 14:30:55 +0100
Raw View
--047d7b5d33dad60f1f05157debe5
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
+1 for this proposal.
With reference to placing non-const values in the vtable, that is no-go=E2=
=80=94far
better to store an indirection in the vtable to r/w memory, as already
intimated. This is still better than an indirect call.
--=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/.
--047d7b5d33dad60f1f05157debe5
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div>+1 for this proposal.</div>
<div>=C2=A0</div>
<div>With reference to placing non-const values in the vtable, that is no-g=
o=E2=80=94far better to store an indirection in the vtable to r/w memory, a=
s already intimated.=C2=A0 This is still better than an indirect call.</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 />
--047d7b5d33dad60f1f05157debe5--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 7 May 2015 16:03:23 -0700 (PDT)
Raw View
------=_Part_1473_1090494479.1431039803530
Content-Type: multipart/alternative;
boundary="----=_Part_1474_1610600814.1431039803530"
------=_Part_1474_1610600814.1431039803530
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, May 7, 2015 at 6:30:56 AM UTC-7, Douglas Boffey wrote:
>
> +1 for this proposal.
> =20
> With reference to placing non-const values in the vtable, that is=20
> no-go=E2=80=94far better to store an indirection in the vtable to r/w mem=
ory, as=20
> already intimated. This is still better than an indirect call.
>
Also notice that once the fundamental "store const data in the vtable"=20
mechanism is in place, implementing "indirection to non-const data" can be=
=20
done in user code with basically zero extra overhead. If at the same time=
=20
we can remove the silly historical restriction that forces us to define=20
static data members out-of-line, a bunch of this boilerplate disappears.
I'm assuming that we would allow virtual static data members to be defined=
=20
in-line (just as we can define virtual member functions in-line and let the=
=20
compiler figure out the linkage). I'm also assuming that virtual static=20
data members of reference type would be allowed.
Lastly: If virtual static data members are added, virtual static member=20
functions should certainly come along for the ride.
class AmputableAnimal {
protected:
struct classdata_ { int legs; };
private:
static classdata_ animaldata;
public:
int legs() const { return classdata.legs; } // non-virtual method=20
works for all derived classes
virtual static classdata_& classdata =3D animaldata;
};
class AmputableCentipede : public AmputableAnimal {
private:
using AmputableAnimal::classdata_;
static classdata_ centipededata;
public:
virtual static classdata_& classdata override =3D centipededata;
};
AmputableAnimal::classdata_ AmputableAnimal::animaldata =3D { 4 };
AmputableAnimal::classdata_ AmputableCentipede::centipededata =3D { 100 };
void amputate_entire_cohort(AmputableAnimal *panimal) {
panimal->classdata.legs -=3D 1;
}
int main() {
auto *dog =3D new AmputableAnimal;
auto *cent1 =3D new AmputableCentipede;
auto *cent2 =3D new AmputableCentipede;
assert(dog->legs() =3D=3D 4);
assert(cent1->legs() =3D=3D 100);
assert(cent2->legs() =3D=3D 100);
amputate_entire_cohort(cent1);
assert(dog->legs() =3D=3D 4);
assert(cent1->legs() =3D=3D 99);
assert(cent2->legs() =3D=3D 99);
}
--=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_1474_1610600814.1431039803530
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, May 7, 2015 at 6:30:56 AM UTC-7, Douglas Boff=
ey wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>+1 for this prop=
osal.</div>
<div> </div>
<div>With reference to placing non-const values in the vtable, that is no-g=
o=E2=80=94far better to store an indirection in the vtable to r/w memory, a=
s already intimated. This is still better than an indirect call.</div=
></blockquote><div><br></div><div>Also notice that once the fundamental "st=
ore const data in the vtable" mechanism is in place, implementing "indirect=
ion to non-const data" can be done in user code with basically zero extra o=
verhead. If at the same time we can remove the silly historical restr=
iction that forces us to define static data members out-of-line, a bunch of=
this boilerplate disappears.</div><div><br></div><div>I'm assuming that we=
would allow virtual static data members to be defined in-line (just as we =
can define virtual member functions in-line and let the compiler figure out=
the linkage). I'm also assuming that virtual static data members of =
reference type would be allowed.</div><div><br></div><div>Lastly: If virtua=
l static data members are added, virtual static member functions should cer=
tainly come along for the ride.</div><div><br></div><div class=3D"prettypri=
nt" style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(18=
7, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">AmputableA=
nimal</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">protected</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> classdata_ </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> legs</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</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>&nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">privat=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">static</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> classdata_ an=
imaldata</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">public</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> legs</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">r=
eturn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> clas=
sdata</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">legs</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</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"> </span><span style=3D"color: #800;" cla=
ss=3D"styled-by-prettify">// non-virtual method works for all derived class=
es</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbs=
p; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
virtual</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">static</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> classdata_</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> classdata </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> animaldata</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">AmputableCentipede</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">public</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">AmputableAnimal</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">private</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">using</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">AmputableAnimal</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">classdata_</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">static</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> classdata_ centipededata</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">public</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">virtual</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">static</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> classdata_</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
classdata </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">=3D</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> centipededata</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
#606;" class=3D"styled-by-prettify">AmputableAnimal</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">classdata_ </span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">AmputableAnimal</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">animaldata </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">4=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify">AmputableAnimal</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">classdata_ </span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">AmputableCentipede</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">centipededata </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-=
prettify">100</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> amputate_entire_cohor=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #606;" class=3D"styled-by-prettify">AmputableAnimal</s=
pan><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">panimal</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</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"style=
d-by-prettify"><br> panimal</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">-></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">classdata</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">legs </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">-=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</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">dog </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">new</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"s=
tyled-by-prettify">AmputableAnimal</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
cent1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">new</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">AmputableCentipede</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #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">cent2 </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">new</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">AmputableCen=
tipede</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> &n=
bsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">asser=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">dog</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">-></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">legs</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by=
-prettify">4</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">assert</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">cent1</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">-></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">legs</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"st=
yled-by-prettify">100</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ce=
nt2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">legs</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" cl=
ass=3D"styled-by-prettify">100</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br> amputate_entire_cohort</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">cent1</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br><br> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">dog</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">-></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">legs</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #066;" class=3D"styled-by-prettify">4</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">cent1</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">-></span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">legs</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #066;" class=3D"styled-by-prettify">99</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">cent2</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">-></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">legs</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #066;" class=3D"styled-by-prettify">99</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><div><br><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_1474_1610600814.1431039803530--
------=_Part_1473_1090494479.1431039803530--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 7 May 2015 18:11:02 -0700 (PDT)
Raw View
------=_Part_1803_42339350.1431047462222
Content-Type: multipart/alternative;
boundary="----=_Part_1804_780368293.1431047462222"
------=_Part_1804_780368293.1431047462222
Content-Type: text/plain; charset=UTF-8
On Thursday, May 7, 2015 at 7:03:23 PM UTC-4, Arthur O'Dwyer wrote:
>
> Lastly: If virtual static data members are added, virtual static member
> functions should certainly come along for the ride.
>
And... what would that mean, exactly?
The point of a virtual static data member is to be able to access a value
per-class, when the class is polymorphic, without having to call a
function. So to access a virtual static data member, you need an instance
of the class.
We already have a way to access polymorphic functions via an instance of a
class. They're called virtual functions. So what would this "virtual static
member function" actually do?
Bikeshed: note that this suggests that the word "static" is somewhat wrong
here. The variable is not "static" in the usual C++ sense of that term,
since you can only access it through an object instance. Since it is a
polymorphic data member, shouldn't we just call it a "virtual data member,"
with the rider that virtual data members must be declared "constexpr"?
--
---
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_1804_780368293.1431047462222
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Thursday, May 7, 2015 at 7:03:23 PM UTC-4, Arth=
ur O'Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">Lastly: If virtual static data members are added, virtual static member=
functions should certainly come along for the ride.</div></blockquote><div=
><br>And... what would that mean, exactly?<br><br>The point of a virtual st=
atic data member is to be able to access a value per-class, when the class =
is polymorphic, without having to call a function. So to access a virtual s=
tatic data member, you need an instance of the class.<br><br>We already hav=
e a way to access polymorphic functions via an instance of a class. They're=
called virtual functions. So what would this "virtual static member functi=
on" actually do?<br><br>Bikeshed: note that this suggests that the word "st=
atic" is somewhat wrong here. The variable is not "static" in the usual C++=
sense of that term, since you can only access it through an object instanc=
e. Since it is a polymorphic data member, shouldn't we just call it a "virt=
ual data member," with the rider that virtual data members must be declared=
"constexpr"?<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_1804_780368293.1431047462222--
------=_Part_1803_42339350.1431047462222--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Fri, 8 May 2015 16:31:27 -0700 (PDT)
Raw View
------=_Part_2707_1640560258.1431127887673
Content-Type: multipart/alternative;
boundary="----=_Part_2708_1353712373.1431127887673"
------=_Part_2708_1353712373.1431127887673
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, May 7, 2015 at 6:11:02 PM UTC-7, Nicol Bolas wrote:
>
> On Thursday, May 7, 2015 at 7:03:23 PM UTC-4, Arthur O'Dwyer wrote:
>>
>> Lastly: If virtual static data members are added, virtual static member=
=20
>> functions should certainly come along for the ride.
>>
>
> And... what would that mean, exactly?
>
> The point of a virtual static data member is to be able to access a value=
=20
> per-class, when the class is polymorphic, without having to call a=20
> function. So to access a virtual static data member, you need an instance=
=20
> of the class.
>
> We already have a way to access polymorphic functions via an instance of =
a=20
> class. They're called virtual functions. So what would this "virtual stat=
ic=20
> member function" actually do?
>
The implementation (in terms of virtual static data members) would be=20
exactly:
class Animal {
static std::string scientific_name(int levels) { ... } // a=20
non-virtual static method
virtual static constexpr std::string (*pscientific_name)(int) =3D &
scientific_name; // a virtual static data member
};
void print_name(Animal *a, int kpcofgs) {
std::cout << a->pscientific_name(kpcofgs) << std::endl;
};
except that we would add syntactic sugar so that it could be written as:
class Animal {
virtual static std::string scientific_name(int levels) { ... } // a=20
virtual static method
};
void print_name(Animal *a, int kpcofgs) {
std::cout << a->scientific_name(kpcofgs) << std::endl;
};
The efficiency advantage over non-static virtual methods should be obvious=
=20
at this point, but, for the casual audience:
- No implicit *this pointer (reducing register pressure)
- Corollary to the above: no thunks or this-pointer adjustments needed
- Enforcement that no child class can ever (ab)use *this inside their=20
implementation of scientific_name
- Symmetry with non-static virtual methods
=20
> Bikeshed: note that this suggests that the word "static" is somewhat wron=
g=20
> here. The variable is not "static" in the usual C++ sense of that term,=
=20
> since you can only access it through an object instance. Since it is a=20
> polymorphic data member, shouldn't we just call it a "virtual data member=
,"=20
> with the rider that virtual data members must be declared "constexpr"?
>
Nope; data members that are shared among all instances of a class are=20
properly described as "static".
The only data members that should ever be described as "non-static" are=20
data members that are duplicated by all instances of their class.
You are correct that forcing virtual static data members to be "const" is=
=20
not enough; we must force them to be "constexpr" (or perhaps "const" as=20
long as they're initialized by constant-expressions? and I'm not sure how=
=20
reference types interact with "constexpr"? but that's the general idea,=20
yeah). Obviously
class Tester {
static const int x =3D puts("hello"); // acceptable
virtual static const int x =3D puts("hello"); // UNACCEPTABLE
};
must not be allowed.
=E2=80=93Arthur
--=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_2708_1353712373.1431127887673
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, May 7, 2015 at 6:11:02 PM UTC-7, Nicol Bolas =
wrote:<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">On Thur=
sday, May 7, 2015 at 7:03:23 PM UTC-4, Arthur O'Dwyer wrote:<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">Lastly: If virtual static data me=
mbers are added, virtual static member functions should certainly come alon=
g for the ride.</div></blockquote><div><br>And... what would that mean, exa=
ctly?<br><br>The point of a virtual static data member is to be able to acc=
ess a value per-class, when the class is polymorphic, without having to cal=
l a function. So to access a virtual static data member, you need an instan=
ce of the class.<br><br>We already have a way to access polymorphic functio=
ns via an instance of a class. They're called virtual functions. So what wo=
uld this "virtual static member function" actually do?<br></div></div></blo=
ckquote><div><br></div><div>The implementation (in terms of virtual static =
data members) would be exactly:</div><div><br></div><div class=3D"prettypri=
nt" style=3D"background-color: rgb(250, 250, 250); border: 1px solid rgb(18=
7, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">class</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Animal</sp=
an><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> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">static</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">string</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> scientific_name</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> levels</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">// a non-virtual static method</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">virtual</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">static</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">constexpr</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">string</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">pscie=
ntific_name</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">=3D</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"styled-by-prettify">scientific_name</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// a virtual static data member</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> print_name</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Animal</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">a</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> kpcofgs</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</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> std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
<<</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-></spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">pscientific_nam=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">kpcofgs</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">)</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"> std</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">endl</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></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">};</span></div></code></div><div><br></div><div>except that we would add=
syntactic sugar so that it could be written as:</div><div><br></div><div c=
lass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border:=
1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-pre=
ttify">Animal</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> &nbs=
p; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">virtual=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">static</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> scientific_name</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> levels</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><s=
pan 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"> </span><span style=3D"color: #=
800;" class=3D"styled-by-prettify">// a virtual static method</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> print_name</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Animal</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=
">a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> kpcofgs</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)</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"style=
d-by-prettify"><br> std</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">cout </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><<</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">-></span><span style=3D"color: #000;" class=3D"styled-by-prettify">sc=
ientific_name</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">kpcofg=
s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify"><<</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">endl</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">};</span></div></code></div><div><div><br></div></div><div>The =
efficiency advantage over non-static virtual methods should be obvious at t=
his point, but, for the casual audience:<br></div><div>- No implicit *this =
pointer (reducing register pressure)</div><div>- Corollary to the above: no=
thunks or this-pointer adjustments needed</div><div>- Enforcement that no =
child class can ever (ab)use *this inside their implementation of scientifi=
c_name</div><div>- Symmetry with non-static virtual methods</div><div> =
;</div><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"><div>B=
ikeshed: note that this suggests that the word "static" is somewhat wrong h=
ere. The variable is not "static" in the usual C++ sense of that term, sinc=
e you can only access it through an object instance. Since it is a polymorp=
hic data member, shouldn't we just call it a "virtual data member," with th=
e rider that virtual data members must be declared "constexpr"?<br></div></=
div></blockquote><div><br></div><div>Nope; data members that are shared amo=
ng all instances of a class are properly described as "static".</div><div>T=
he only data members that should ever be described as "non-static" are data=
members that are duplicated by all instances of their class.</div><div><br=
></div><div><br></div><div>You are correct that forcing virtual static data=
members to be "const" is not enough; we must force them to be "constexpr" =
(or perhaps "const" as long as they're initialized by constant-expressions?=
and I'm not sure how reference types interact with "constexpr"? but that's=
the general idea, yeah). Obviously</div><div><br></div><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border: 1px solid rg=
b(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">class</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Tester=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">static</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> puts</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"hello"=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">// acceptable</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">virtual</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">static</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> puts</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #080;" class=3D"styled-by-prettify">"hello"</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">// UNACCEPTABLE</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></span></div></code></div><d=
iv><br></div><div>must not be allowed.</div><div><br></div><div>=E2=80=93Ar=
thur</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_2708_1353712373.1431127887673--
------=_Part_2707_1640560258.1431127887673--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 8 May 2015 23:47:29 -0700 (PDT)
Raw View
------=_Part_20_780428348.1431154049848
Content-Type: multipart/alternative;
boundary="----=_Part_21_1976612607.1431154049848"
------=_Part_21_1976612607.1431154049848
Content-Type: text/plain; charset=UTF-8
On Friday, May 8, 2015 at 7:31:27 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Thursday, May 7, 2015 at 6:11:02 PM UTC-7, Nicol Bolas wrote:
>>
>> On Thursday, May 7, 2015 at 7:03:23 PM UTC-4, Arthur O'Dwyer wrote:
>>>
>>> Lastly: If virtual static data members are added, virtual static member
>>> functions should certainly come along for the ride.
>>>
>>
>> And... what would that mean, exactly?
>>
>> The point of a virtual static data member is to be able to access a value
>> per-class, when the class is polymorphic, without having to call a
>> function. So to access a virtual static data member, you need an instance
>> of the class.
>>
>> We already have a way to access polymorphic functions via an instance of
>> a class. They're called virtual functions. So what would this "virtual
>> static member function" actually do?
>>
>
> The implementation (in terms of virtual static data members) would be
> exactly:
>
> class Animal {
> static std::string scientific_name(int levels) { ... } // a
> non-virtual static method
> virtual static constexpr std::string (*pscientific_name)(int) = &
> scientific_name; // a virtual static data member
> };
>
> void print_name(Animal *a, int kpcofgs) {
> std::cout << a->pscientific_name(kpcofgs) << std::endl;
> };
>
> except that we would add syntactic sugar so that it could be written as:
>
> class Animal {
> virtual static std::string scientific_name(int levels) { ... } // a
> virtual static method
> };
>
> void print_name(Animal *a, int kpcofgs) {
> std::cout << a->scientific_name(kpcofgs) << std::endl;
> };
>
> The efficiency advantage over non-static virtual methods should be obvious
> at this point, but, for the casual audience:
> - No implicit *this pointer (reducing register pressure)
> - Corollary to the above: no thunks or this-pointer adjustments needed
> - Enforcement that no child class can ever (ab)use *this inside their
> implementation of scientific_name
> - Symmetry with non-static virtual methods
>
So it's one advantage that you're counting three times (the fact that the
function doesn't take a `this` pointer).
I don't buy the notion that this reduces register pressure. Why? Because
`this` already has to be in a register. Remember: this is a polymorphic
dispatch. So you need to use `this` to access the vtable or whatever other
data structure the implementation uses to store virtual functions. So you
already have a `this` at the call cite, thus you've had to reserve a
register for both it and the vtable. The only register pressure that could
still be reduced is in the actual function call itself, and really, that's
getting into micro-optimization territory.
After all, it's still a virtual dispatch. The time you spent loading that
vtable and getting the function pointer out of it hurts far more than any
register pressure.
Yes, you don't have to do thunking/this-pointer-fixup. But that is an
implementation and class-hierarchy-specific issue. If you're only doing
single inheritance, and your implementation puts the vtable pointer at the
top of the object, then thunking never has to happen regardless.
Are there cases where thunking does happen on most implementations and that
a lack of thunking could help performance? Sure. But I'd like to see some
information about how common those scenarios are and how much of a
performance problem such things are before suggesting this as an
alternative.
Again, it has to compete with the cost of vtable lookup. And I'd bet that
thunking hurts rather less than doing the vtable pointer lookup.
As for making sure that nobody messes with `this`, then make it `const`.
You shouldn't try to prevent perfidy, so don't trouble yourself with people
who will const_cast it away. And if `mutable` members make this a
problem... again, I'd want to see some real facts as to whether this
situation is sufficiently common to bother covering.
>
>> Bikeshed: note that this suggests that the word "static" is somewhat
>> wrong here. The variable is not "static" in the usual C++ sense of that
>> term, since you can only access it through an object instance. Since it is
>> a polymorphic data member, shouldn't we just call it a "virtual data
>> member," with the rider that virtual data members must be declared
>> "constexpr"?
>>
>
> Nope; data members that are shared among all instances of a class are
> properly described as "static".
>
The only data members that should ever be described as "non-static" are
> data members that are duplicated by all instances of their class.
>
That's one element of static data members, but there are many other
elements of them. Here's another: static data members can only be accessed
through the type, not through an object instance.
That's why declaring that they're non-`static` but `constexpr` works. Since
they are `constexpr`, they must be initialized at the class scope. So, if a
`virtual constexpr` data member were actually stored within the class's
instance, then every instance of the same class would get the same value.
Therefore, you can think of the storage being within the class rather than
the instance as purely as an optimization.
To be fair though, it is a strange concept that straddles the line. From
the perspective of someone using the class, it is per-instance data, since
it can vary from (polymorphic) instance to instance. Just as member
pointers to virtual functions can vary from (polymorphic) instance to
instance. Yet, the storage for the data is necessarily with the class; such
data members do not take up per-instance storage.
I guess what matters is which perspective matters more to you: how you use
the member or where the data is stored.
--
---
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_21_1976612607.1431154049848
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, May 8, 2015 at 7:31:27 PM UTC-4, Arthur=
O'Dwyer 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"ltr=
">On Thursday, May 7, 2015 at 6:11:02 PM UTC-7, Nicol Bolas wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Thursday, May 7, 2015 at=
7:03:23 PM UTC-4, Arthur O'Dwyer wrote:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr">Lastly: If virtual static data members are added, vir=
tual static member functions should certainly come along for the ride.</div=
></blockquote><div><br>And... what would that mean, exactly?<br><br>The poi=
nt of a virtual static data member is to be able to access a value per-clas=
s, when the class is polymorphic, without having to call a function. So to =
access a virtual static data member, you need an instance of the class.<br>=
<br>We already have a way to access polymorphic functions via an instance o=
f a class. They're called virtual functions. So what would this "virtual st=
atic member function" actually do?<br></div></div></blockquote><div><br></d=
iv><div>The implementation (in terms of virtual static data members) would =
be exactly:</div><div><br></div><div style=3D"background-color:rgb(250,250,=
250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><sp=
an style=3D"color:#008">class</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#606">Animal</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">{</span><span style=3D"color:#000"><br> =
</span><span style=3D"color:#008">static</span><span style=3D"color:#000">=
std</span><span style=3D"color:#660">::</span><span style=3D"color:#008">s=
tring</span><span style=3D"color:#000"> scientific_name</span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">int</span><span style=3D=
"color:#000"> levels</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">...</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">}</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#800">// a non-virtual static method<=
/span><span style=3D"color:#000"><br> </span><span style=3D"co=
lor:#008">virtual</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">static</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">constexpr</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#008">string</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">(*</span><span style=
=3D"color:#000">pscientific_name</span><span style=3D"color:#660">)(</span>=
<span style=3D"color:#008">int</span><span style=3D"color:#660">)</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">&</span><span s=
tyle=3D"color:#000">scientific_name</span><span style=3D"color:#660">;</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#800">// a =
virtual static data member</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#660">};</span><span style=3D"color:#000"><br><br></span><=
span style=3D"color:#008">void</span><span style=3D"color:#000"> print_name=
</span><span style=3D"color:#660">(</span><span style=3D"color:#606">Animal=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">*</spa=
n><span style=3D"color:#000">a</span><span style=3D"color:#660">,</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">int</span><span =
style=3D"color:#000"> kpcofgs</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br> std</span><span style=3D"color:#660">::=
</span><span style=3D"color:#000">cout </span><span style=3D"color:#660">&l=
t;<</span><span style=3D"color:#000"> a</span><span style=3D"color:#660"=
>-></span><span style=3D"color:#000">pscientific_name</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">kpcofgs</span><span styl=
e=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660"><<</span><span style=3D"color:#000"> std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">endl</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">};</span></div></code></div><div><br></div><div>except that=
we would add syntactic sugar so that it could be written as:</div><div><br=
></div><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb=
(187,187,187);word-wrap:break-word"><code><div><span style=3D"color:#008">c=
lass</span><span style=3D"color:#000"> </span><span style=3D"color:#606">An=
imal</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{<=
/span><span style=3D"color:#000"><br> </span><span style=3D"co=
lor:#008">virtual</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">static</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#008">string</span><span styl=
e=3D"color:#000"> scientific_name</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#008">int</span><span style=3D"color:#000"> levels</sp=
an><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">...</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">}</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#800">// a virtual static method</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#660">};</span><span style=3D"color:#000=
"><br><br></span><span style=3D"color:#008">void</span><span style=3D"color=
:#000"> print_name</span><span style=3D"color:#660">(</span><span style=3D"=
color:#606">Animal</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">*</span><span style=3D"color:#000">a</span><span style=3D"color=
:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008=
">int</span><span style=3D"color:#000"> kpcofgs</span><span style=3D"color:=
#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>{</span><span style=3D"color:#000"><br> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">cout </span><span style=
=3D"color:#660"><<</span><span style=3D"color:#000"> a</span><span st=
yle=3D"color:#660">-></span><span style=3D"color:#000">scientific_name</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">kpcofgs<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660"><<</span><span style=3D"color:#000"> std<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#000">endl</=
span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#660">};</span></div></code></div><div><div><br></d=
iv></div><div>The efficiency advantage over non-static virtual methods shou=
ld be obvious at this point, but, for the casual audience:<br></div><div>- =
No implicit *this pointer (reducing register pressure)</div><div>- Corollar=
y to the above: no thunks or this-pointer adjustments needed</div><div>- En=
forcement that no child class can ever (ab)use *this inside their implement=
ation of scientific_name</div><div>- Symmetry with non-static virtual metho=
ds</div></div></blockquote><div><br>So it's one advantage that you're count=
ing three times (the fact that the function doesn't take a `this` pointer).=
<br><br>I don't buy the notion that this reduces register pressure. Why? Be=
cause `this` already has to be in a register. Remember: this is a polymorph=
ic dispatch. So you need to use `this` to access the vtable or whatever oth=
er data structure the implementation uses to store virtual functions. So yo=
u already have a `this` at the call cite, thus you've had to reserve a regi=
ster for both it and the vtable. The only register pressure that could stil=
l be reduced is in the actual function call itself, and really, that's gett=
ing into micro-optimization territory.<br><br>After all, it's still a virtu=
al dispatch. The time you spent loading that vtable and getting the functio=
n pointer out of it hurts far more than any register pressure.<br><br>Yes, =
you don't have to do thunking/this-pointer-fixup. But that is an implementa=
tion and class-hierarchy-specific issue. If you're only doing single inheri=
tance, and your implementation puts the vtable pointer at the top of the ob=
ject, then thunking never has to happen regardless.<br><br>Are there cases =
where thunking does happen on most implementations and that a lack of thunk=
ing could help performance? Sure. But I'd like to see some information abou=
t how common those scenarios are and how much of a performance problem such=
things are before suggesting this as an alternative.<br><br>Again, it has =
to compete with the cost of vtable lookup. And I'd bet that thunking hurts =
rather less than doing the vtable pointer lookup.<br><br>As for making sure=
that nobody messes with `this`, then make it `const`. You shouldn't try to=
prevent perfidy, so don't trouble yourself with people who will const_cast=
it away. And if `mutable` members make this a problem... again, I'd want t=
o see some real facts as to whether this situation is sufficiently common t=
o bother covering.<br><br></div><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"><div> </div><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"><div>Bikeshed: note that this suggests that the word "sta=
tic" is somewhat wrong here. The variable is not "static" in the usual C++ =
sense of that term, since you can only access it through an object instance=
.. Since it is a polymorphic data member, shouldn't we just call it a "virtu=
al data member," with the rider that virtual data members must be declared =
"constexpr"?<br></div></div></blockquote><div><br></div><div>Nope; data mem=
bers that are shared among all instances of a class are properly described =
as "static".</div></div></blockquote><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div dir=3D"ltr"><div>The only data members that should ever be desc=
ribed as "non-static" are data members that are duplicated by all instances=
of their class.</div></div></blockquote><div><br>That's one element of sta=
tic data members, but there are many other elements of them. Here's another=
: static data members can only be accessed through the type, not through an=
object instance.<br><br>That's why declaring that they're non-`static` but=
`constexpr` works. Since they are `constexpr`, they must be initialized at=
the class scope. So, if a `virtual constexpr` data member were actually st=
ored within the class's instance, then every instance of the same class wou=
ld get the same value. Therefore, you can think of the storage being within=
the class rather than the instance as purely as an optimization.<br><br>To=
be fair though, it is a strange concept that straddles the line. From the =
perspective of someone using the class, it is per-instance data, since it c=
an vary from (polymorphic) instance to instance. Just as member pointers to=
virtual functions can vary from (polymorphic) instance to instance. Yet, t=
he storage for the data is necessarily with the class; such data members do=
not take up per-instance storage.<br><br>I guess what matters is which per=
spective matters more to you: how you use the member or where the data is s=
tored.<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_21_1976612607.1431154049848--
------=_Part_20_780428348.1431154049848--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sat, 9 May 2015 16:19:41 -0700
Raw View
--047d7bb04b0e1f22c80515ae61fb
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Fri, May 8, 2015 at 11:47 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Friday, May 8, 2015 at 7:31:27 PM UTC-4, Arthur O'Dwyer wrote:
>>
>> On Thursday, May 7, 2015 at 6:11:02 PM UTC-7, Nicol Bolas wrote:
>>>
>>> On Thursday, May 7, 2015 at 7:03:23 PM UTC-4, Arthur O'Dwyer wrote:
>>>>
>>>> Lastly: If virtual static data members are added, virtual static membe=
r
>>>> functions should certainly come along for the ride.
>>>>
>>>
>>> And... what would that mean, exactly?
>>>
>>> We already have a way to access polymorphic functions via an instance o=
f
>>> a class. They're called virtual functions. So what would this "virtual
>>> static member function" actually do?
>>>
>>
>> The implementation (in terms of virtual static data members) would be
>> exactly:
>>
>> class Animal {
>> static std::string scientific_name(int levels) { ... } // a
>> non-virtual static method
>> virtual static constexpr std::string (*pscientific_name)(int) =3D &
>> scientific_name; // a virtual static data member
>> };
>>
>> void print_name(Animal *a, int kpcofgs) {
>> std::cout << a->pscientific_name(kpcofgs) << std::endl;
>> };
>>
>> except that we would add syntactic sugar so that it could be written as:
>>
>> class Animal {
>> virtual static std::string scientific_name(int levels) { ... } // a
>> virtual static method
>> };
>>
>> void print_name(Animal *a, int kpcofgs) {
>> std::cout << a->scientific_name(kpcofgs) << std::endl;
>> };
>>
>> The efficiency advantage over non-static virtual methods should be
>> obvious at this point, but, for the casual audience:
>> - No implicit *this pointer (reducing register pressure)
>> - Corollary to the above: no thunks or this-pointer adjustments needed
>> - Enforcement that no child class can ever (ab)use *this inside their
>> implementation of scientific_name
>> - Symmetry with non-static virtual methods
>>
>
> So it's one advantage that you're counting three times (the fact that the
> function doesn't take a `this` pointer).
>
Two efficiency advantages (no register pressure and no need for fixup) and
one semantic issue (enforcement of a constraint on all derived classes)
that would be considered an advantage by one audience but perhaps not by
others.
I don't buy the notion that this reduces register pressure. Why? Because
> `this` already has to be in a register. Remember: this is a polymorphic
> dispatch. So you need to use `this` to access the vtable or whatever othe=
r
> data structure the implementation uses to store virtual functions. So you
> already have a `this` at the call cite, thus you've had to reserve a
> register for both it and the vtable. The only register pressure that coul=
d
> still be reduced is in the actual function call itself, and really, that'=
s
> getting into micro-optimization territory.
>
> After all, it's still a virtual dispatch. The time you spent loading that
> vtable and getting the function pointer out of it hurts far more than any
> register pressure.
>
You can't complain about "micro-optimization territory" and then turn
around and complain about the cost of a single memory access. :) You have
to pick one side or the other. I'm coming down on the side of
micro-optimization: C++ shouldn't allow any space between itself and the
metal into which a better-designed language could sneak. C++ should *be*
that better-designed language.
> Nope; data members that are shared among all instances of a class are
>> properly described as "static".
>>
> The only data members that should ever be described as "non-static" are
>> data members that are duplicated by all instances of their class.
>>
>
> That's one element of static data members, but there are many other
> elements of them. Here's another: static data members can only be accesse=
d
> through the type, not through an object instance.
>
Aha, this might be the root cause of our disagreement! You'll be surprised
to learn that static data members *can* be accessed through an object
instance:
http://melpon.org/wandbox/permlink/fa4GTexBT1dqoqT2
struct Vegetable {
static int roots;
};
int Vegetable::roots =3D 5;
int main()
{
Vegetable v;
return v.roots;
}
> That's why declaring that they're non-`static` but `constexpr` works.
> Since they are `constexpr`, they must be initialized at the class scope.
> So, if a `virtual constexpr` data member were actually stored within the
> class's instance, then every instance of the same class would get the sam=
e
> value.
>
s/class's instance/class definition/
And yes, that's precisely where it *is* stored, and precisely what *does*
happen. Take another look at my example code from earlier: all
AmputableCentipedes see the same number of legs, because legs is a static
data member of AmputableCentipede. But AmputableCentipede::legs is still
looked up via virtual dispatch, so that it's accessible even through a
pointer-to-instance of AmputableAnimal base class type. The value of a->leg=
s
depends on the dynamic type of *a =E2=80=94 even though it cannot depend up=
on the
runtime *value* of *a.
> Therefore, you can think of the storage being within the class rather tha=
n
> the instance as purely as an optimization.
>
Nope; if you're thinking of "virtual" as purely an efficiency optimization,
you haven't yet grasped its power.
=E2=80=93Arthur
--=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/.
--047d7bb04b0e1f22c80515ae61fb
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Fri, May 8, 2015 at 11:47 PM, Nicol Bolas <span dir=3D"=
ltr"><<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson=
@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-l=
eft-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D"">On Frid=
ay, May 8, 2015 at 7:31:27 PM UTC-4, Arthur O'Dwyer wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1p=
x;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1=
ex"><div dir=3D"ltr">On Thursday, May 7, 2015 at 6:11:02 PM UTC-7, Nicol Bo=
las wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-sty=
le:solid;padding-left:1ex"><div dir=3D"ltr">On Thursday, May 7, 2015 at 7:0=
3:23 PM UTC-4, Arthur O'Dwyer wrote:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rg=
b(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">L=
astly: If virtual static data members are added, virtual static member func=
tions should certainly come along for the ride.</div></blockquote><div><br>=
And... what would that mean, exactly?<br><br>We already have a way to acces=
s polymorphic functions via an instance of a class. They're called virt=
ual functions. So what would this "virtual static member function"=
; actually do?<br></div></div></blockquote><div><br></div><div>The implemen=
tation (in terms of virtual static data members) would be exactly:</div><di=
v><br></div><div style=3D"background-color:rgb(250,250,250);border:1px soli=
d rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"color:rg=
b(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> </span><span styl=
e=3D"color:rgb(102,0,102)">Animal</span><span style=3D"color:rgb(0,0,0)"> <=
/span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb=
(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">static=
</span><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb=
(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><span=
style=3D"color:rgb(0,0,0)"> scientific_name</span><span style=3D"color:rgb=
(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">int</span><span sty=
le=3D"color:rgb(0,0,0)"> levels</span><span style=3D"color:rgb(102,102,0)">=
)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"=
color:rgb(102,102,0)">...</span><span style=3D"color:rgb(0,0,0)"> </span><s=
pan style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,0,0)"=
> =C2=A0</span><span style=3D"color:rgb(136,0,0)">// a non-virtual static m=
ethod</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span=
style=3D"color:rgb(0,0,136)">virtual</span><span style=3D"color:rgb(0,0,0)=
"> </span><span style=3D"color:rgb(0,0,136)">static</span><span style=3D"co=
lor:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">constexpr</span>=
<span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,10=
2,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">(*</span=
><span style=3D"color:rgb(0,0,0)">pscientific_name</span><span style=3D"col=
or:rgb(102,102,0)">)(</span><span style=3D"color:rgb(0,0,136)">int</span><s=
pan style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"colo=
r:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">&</span><spa=
n style=3D"color:rgb(0,0,0)">scientific_name</span><span style=3D"color:rgb=
(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"> =C2=A0</span><span s=
tyle=3D"color:rgb(136,0,0)">// a virtual static data member</span><span sty=
le=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};<=
/span><span style=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"color:=
rgb(0,0,136)">void</span><span style=3D"color:rgb(0,0,0)"> print_name</span=
><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,=
0,102)">Animal</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)">a</span>=
<span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"colo=
r:rgb(0,0,0)"> kpcofgs</span><span style=3D"color:rgb(102,102,0)">)</span><=
span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)=
">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">=
cout </span><span style=3D"color:rgb(102,102,0)"><<</span><span style=
=3D"color:rgb(0,0,0)"> a</span><span style=3D"color:rgb(102,102,0)">-></=
span><span style=3D"color:rgb(0,0,0)">pscientific_name</span><span style=3D=
"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">kpcofgs</sp=
an><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,=
0,0)"> </span><span style=3D"color:rgb(102,102,0)"><<</span><span sty=
le=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::<=
/span><span style=3D"color:rgb(0,0,0)">endl</span><span style=3D"color:rgb(=
102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=
=3D"color:rgb(102,102,0)">};</span></div></code></div><div><br></div><div>e=
xcept that we would add syntactic sugar so that it could be written as:</di=
v><div><br></div><div style=3D"background-color:rgb(250,250,250);border:1px=
solid rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"col=
or:rgb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> </span><span=
style=3D"color:rgb(102,0,102)">Animal</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"colo=
r:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">v=
irtual</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(0,0,136)">static</span><span style=3D"color:rgb(0,0,0)"> std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)=
">string</span><span style=3D"color:rgb(0,0,0)"> scientific_name</span><spa=
n style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)"=
>int</span><span style=3D"color:rgb(0,0,0)"> levels</span><span style=3D"co=
lor:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span =
style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(102,102,0)">...</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</span><span style=
=3D"color:rgb(0,0,0)"> =C2=A0</span><span style=3D"color:rgb(136,0,0)">// a=
virtual static method</span><span style=3D"color:rgb(0,0,0)"><br></span><s=
pan style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)=
"><br><br></span><span style=3D"color:rgb(0,0,136)">void</span><span style=
=3D"color:rgb(0,0,0)"> print_name</span><span style=3D"color:rgb(102,102,0)=
">(</span><span style=3D"color:rgb(102,0,102)">Animal</span><span style=3D"=
color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">*</span><spa=
n style=3D"color:rgb(0,0,0)">a</span><span style=3D"color:rgb(102,102,0)">,=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,=
0,136)">int</span><span style=3D"color:rgb(0,0,0)"> kpcofgs</span><span sty=
le=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </spa=
n><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0=
,0)"><br>=C2=A0 =C2=A0 std</span><span style=3D"color:rgb(102,102,0)">::</s=
pan><span style=3D"color:rgb(0,0,0)">cout </span><span style=3D"color:rgb(1=
02,102,0)"><<</span><span style=3D"color:rgb(0,0,0)"> a</span><span s=
tyle=3D"color:rgb(102,102,0)">-></span><span style=3D"color:rgb(0,0,0)">=
scientific_name</span><span style=3D"color:rgb(102,102,0)">(</span><span st=
yle=3D"color:rgb(0,0,0)">kpcofgs</span><span style=3D"color:rgb(102,102,0)"=
>)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,102,0)"><<</span><span style=3D"color:rgb(0,0,0)"> std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">=
endl</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"colo=
r:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};</span></di=
v></code></div><div><div><br></div></div><div>The efficiency advantage over=
non-static virtual methods should be obvious at this point, but, for the c=
asual audience:<br></div><div>- No implicit *this pointer (reducing registe=
r pressure)</div><div>- Corollary to the above: no thunks or this-pointer a=
djustments needed</div><div>- Enforcement that no child class can ever (ab)=
use *this inside their implementation of scientific_name</div><div>- Symmet=
ry with non-static virtual methods</div></div></blockquote></span><div><br>=
So it's one advantage that you're counting three times (the fact th=
at the function doesn't take a `this` pointer).<br></div></div></blockq=
uote><div><br></div><div>Two efficiency advantages (no register pressure an=
d no need for fixup) and one semantic issue (enforcement of a constraint on=
all derived classes) that would be considered an advantage by one audience=
but perhaps not by others.</div><div>=C2=A0</div><div><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width=
:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-lef=
t:1ex"><div dir=3D"ltr"><div>I don't buy the notion that this reduces r=
egister pressure. Why? Because `this` already has to be in a register. Reme=
mber: this is a polymorphic dispatch. So you need to use `this` to access t=
he vtable or whatever other data structure the implementation uses to store=
virtual functions. So you already have a `this` at the call cite, thus you=
've had to reserve a register for both it and the vtable. The only regi=
ster pressure that could still be reduced is in the actual function call it=
self, and really, that's getting into micro-optimization territory.<br>=
<br>After all, it's still a virtual dispatch. The time you spent loadin=
g that vtable and getting the function pointer out of it hurts far more tha=
n any register pressure.<br></div></div></blockquote><div><br></div><div>Yo=
u can't complain about "micro-optimization territory" and the=
n turn around and complain about the cost of a single memory access. :) =C2=
=A0You have to pick one side or the other. I'm coming down on the side =
of micro-optimization: C++ shouldn't allow any space between itself and=
the metal into which a better-designed language could sneak.=C2=A0 C++ sho=
uld <i>be</i> that better-designed language.</div><div><br></div><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D""><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;=
border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex=
"><div dir=3D"ltr"><div>Nope; data members that are shared among all instan=
ces of a class are properly described as "static".</div></div></b=
lockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-sty=
le:solid;padding-left:1ex"><div dir=3D"ltr"><div>The only data members that=
should ever be described as "non-static" are data members that a=
re duplicated by all instances of their class.</div></div></blockquote></sp=
an><div><br>That's one element of static data members, but there are ma=
ny other elements of them. Here's another: static data members can only=
be accessed through the type, not through an object instance.<br></div></d=
iv></blockquote><div><br></div><div>Aha, this might be the root cause of ou=
r disagreement!=C2=A0 You'll be surprised to learn that static data mem=
bers <i>can</i> be accessed through an object instance:</div><div><a href=
=3D"http://melpon.org/wandbox/permlink/fa4GTexBT1dqoqT2">http://melpon.org/=
wandbox/permlink/fa4GTexBT1dqoqT2<br></a></div><div><br></div></div></div><=
blockquote style=3D"margin:0 0 0 40px;border:none;padding:0px"><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div><div><font face=3D"monospa=
ce, monospace">struct Vegetable {</font></div></div></div></div><div class=
=3D"gmail_extra"><div class=3D"gmail_quote"><div><div><font face=3D"monospa=
ce, monospace">=C2=A0 =C2=A0 static int roots;</font></div></div></div></di=
v><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div><div><font fac=
e=3D"monospace, monospace">};</font></div></div></div></div><div class=3D"g=
mail_extra"><div class=3D"gmail_quote"><div><div><font face=3D"monospace, m=
onospace">int Vegetable::roots =3D 5;</font></div></div></div></div><div cl=
ass=3D"gmail_extra"><div class=3D"gmail_quote"><div><div><font face=3D"mono=
space, monospace"><br></font></div></div></div></div><div class=3D"gmail_ex=
tra"><div class=3D"gmail_quote"><div><div><font face=3D"monospace, monospac=
e">int main()</font></div></div></div></div><div class=3D"gmail_extra"><div=
class=3D"gmail_quote"><div><div><font face=3D"monospace, monospace">{</fon=
t></div></div></div></div><div class=3D"gmail_extra"><div class=3D"gmail_qu=
ote"><div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 Vegetable =
v;</font></div></div></div></div><div class=3D"gmail_extra"><div class=3D"g=
mail_quote"><div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 ret=
urn v.roots;</font></div></div></div></div><div class=3D"gmail_extra"><div =
class=3D"gmail_quote"><div><div><font face=3D"monospace, monospace">}</font=
></div></div></div></div></blockquote><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left=
-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=
=3D"ltr"><div>That's why declaring that they're non-`static` but `c=
onstexpr` works. Since they are `constexpr`, they must be initialized at th=
e class scope. So, if a `virtual constexpr` data member were actually store=
d within the class's instance, then every instance of the same class wo=
uld get the same value.</div></div></blockquote><div><br></div><div>s/class=
's instance/class definition/</div><div>And yes, that's precisely w=
here it <i><b>is</b></i> stored, and precisely what <i><b>does</b></i> happ=
en. Take another look at my example code from earlier: all AmputableCentipe=
des see the same number of legs, because <font face=3D"monospace, monospace=
">legs</font> is a static data member of AmputableCentipede. But <font face=
=3D"monospace, monospace">AmputableCentipede::legs</font> is still looked u=
p via virtual dispatch, so that it's accessible even through a pointer-=
to-instance of <font face=3D"monospace, monospace">AmputableAnimal</font> b=
ase class type. The value of <font face=3D"monospace, monospace">a->legs=
</font> depends on the dynamic type of <font face=3D"monospace, monospace">=
*a</font>=C2=A0=E2=80=94 even though it cannot depend upon the runtime <i>v=
alue</i> of <font face=3D"monospace, monospace">*a</font>.</div><div>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:s=
olid;padding-left:1ex"><div dir=3D"ltr"><div> Therefore, you can think of t=
he storage being within the class rather than the instance as purely as an =
optimization.<br></div></div></blockquote><div><br></div><div>Nope; if you&=
#39;re thinking of "virtual" as purely an efficiency optimization=
, you haven't yet grasped its power.</div><div><br></div><div>=E2=80=93=
Arthur</div></div></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 />
--047d7bb04b0e1f22c80515ae61fb--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 9 May 2015 18:44:29 -0700 (PDT)
Raw View
------=_Part_3749_1995041102.1431222269948
Content-Type: multipart/alternative;
boundary="----=_Part_3750_1743294827.1431222269949"
------=_Part_3750_1743294827.1431222269949
Content-Type: text/plain; charset=UTF-8
On Saturday, May 9, 2015 at 7:19:43 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Fri, May 8, 2015 at 11:47 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
>
>> On Friday, May 8, 2015 at 7:31:27 PM UTC-4, Arthur O'Dwyer wrote:
>>>
>>> On Thursday, May 7, 2015 at 6:11:02 PM UTC-7, Nicol Bolas wrote:
>>>>
>>>> On Thursday, May 7, 2015 at 7:03:23 PM UTC-4, Arthur O'Dwyer wrote:
>>>>>
>>>>> Lastly: If virtual static data members are added, virtual static
>>>>> member functions should certainly come along for the ride.
>>>>>
>>>>
>>>> And... what would that mean, exactly?
>>>>
>>>> We already have a way to access polymorphic functions via an instance
>>>> of a class. They're called virtual functions. So what would this "virtual
>>>> static member function" actually do?
>>>>
>>>
>>> The implementation (in terms of virtual static data members) would be
>>> exactly:
>>>
>>> class Animal {
>>> static std::string scientific_name(int levels) { ... } // a
>>> non-virtual static method
>>> virtual static constexpr std::string (*pscientific_name)(int) = &
>>> scientific_name; // a virtual static data member
>>> };
>>>
>>> void print_name(Animal *a, int kpcofgs) {
>>> std::cout << a->pscientific_name(kpcofgs) << std::endl;
>>> };
>>>
>>> except that we would add syntactic sugar so that it could be written as:
>>>
>>> class Animal {
>>> virtual static std::string scientific_name(int levels) { ... } //
>>> a virtual static method
>>> };
>>>
>>> void print_name(Animal *a, int kpcofgs) {
>>> std::cout << a->scientific_name(kpcofgs) << std::endl;
>>> };
>>>
>>> The efficiency advantage over non-static virtual methods should be
>>> obvious at this point, but, for the casual audience:
>>> - No implicit *this pointer (reducing register pressure)
>>> - Corollary to the above: no thunks or this-pointer adjustments needed
>>> - Enforcement that no child class can ever (ab)use *this inside their
>>> implementation of scientific_name
>>> - Symmetry with non-static virtual methods
>>>
>>
>> So it's one advantage that you're counting three times (the fact that the
>> function doesn't take a `this` pointer).
>>
>
> Two efficiency advantages (no register pressure and no need for fixup) and
> one semantic issue (enforcement of a constraint on all derived classes)
> that would be considered an advantage by one audience but perhaps not by
> others.
>
>
> I don't buy the notion that this reduces register pressure. Why? Because
>> `this` already has to be in a register. Remember: this is a polymorphic
>> dispatch. So you need to use `this` to access the vtable or whatever other
>> data structure the implementation uses to store virtual functions. So you
>> already have a `this` at the call cite, thus you've had to reserve a
>> register for both it and the vtable. The only register pressure that could
>> still be reduced is in the actual function call itself, and really, that's
>> getting into micro-optimization territory.
>>
>> After all, it's still a virtual dispatch. The time you spent loading that
>> vtable and getting the function pointer out of it hurts far more than any
>> register pressure.
>>
>
> You can't complain about "micro-optimization territory" and then turn
> around and complain about the cost of a single memory access. :) You have
> to pick one side or the other.
>
Sure I can:
1) It's a micro-optimization and therefore a rounding error in terms of
performance.
2) Even if you consider micro-optimizations relevant for performance, it's
still dwarfed by the memory access. So it's a micro-optimization of a
micro-optimization.
> I'm coming down on the side of micro-optimization: C++ shouldn't allow any
> space between itself and the metal into which a better-designed language
> could sneak. C++ should *be* that better-designed language.
>
That aphorism does not mean that C++ should allow you to do something just
because it gives you more control. It doesn't mean that C++ should give you
ever micro-optimization possible (otherwise, we would have fixed the
performance issues with dynamic_cast and typeid years ago. Not to mention
the performance nightmare of iostream). It merely means that, all things
being equal, C++ should provide you with meaningful low-level functionality.
If there is indeed some "space" between current virtual functions and
static virtual functions... prove it. You can implement virtual functions,
both static and non-static, manually. So do so. Build a test application
that actually gains some measurable improvement in performance by moving
from a non-static virtual function to a static one.
> Nope; data members that are shared among all instances of a class are
>>> properly described as "static".
>>>
>> The only data members that should ever be described as "non-static" are
>>> data members that are duplicated by all instances of their class.
>>>
>>
>> That's one element of static data members, but there are many other
>> elements of them. Here's another: static data members can only be accessed
>> through the type, not through an object instance.
>>
>
> Aha, this might be the root cause of our disagreement! You'll be
> surprised to learn that static data members *can* be accessed through an
> object instance:
>
I stand corrected.
> That's why declaring that they're non-`static` but `constexpr` works.
>> Since they are `constexpr`, they must be initialized at the class scope.
>> So, if a `virtual constexpr` data member were actually stored within the
>> class's instance, then every instance of the same class would get the same
>> value.
>>
>
> s/class's instance/class definition/
>
No, I meant exactly what I said.
If you think of `virtual constexpr` like non-static data members, then they
would be per-instance data, stored in each object. But, since they're all
`constexpr`, every instance would be storing the same value. Therefore, you
could consider centralizing the storage of such values as merely an
optimization. Granted, the standard would enforce the "optimization", but
the user could think of their "staticality" as the result of an enforced
optimization, rather than the whole purpose.
But the overall point is moot, since you can access static data members
like non-static ones. And therefore, there's no confusion for accessing a
static data member with an instance.
--
---
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_3750_1743294827.1431222269949
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Saturday, May 9, 2015 at 7:19:43 PM UTC-4, Arth=
ur O'Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">On Fri, May 8, 2015 at 11:47 PM, Nicol Bolas <span dir=3D"ltr"><<a h=
ref=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"GrebbZ2zr48J=
" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" o=
nclick=3D"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>>=
</span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-lef=
t-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir=
=3D"ltr"><span>On Friday, May 8, 2015 at 7:31:27 PM UTC-4, Arthur O'Dwyer w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bo=
rder-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:so=
lid;padding-left:1ex"><div dir=3D"ltr">On Thursday, May 7, 2015 at 6:11:02 =
PM UTC-7, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,20=
4);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr">On Thursday, =
May 7, 2015 at 7:03:23 PM UTC-4, Arthur O'Dwyer wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border=
-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div=
dir=3D"ltr">Lastly: If virtual static data members are added, virtual stat=
ic member functions should certainly come along for the ride.</div></blockq=
uote><div><br>And... what would that mean, exactly?<br><br>We already have =
a way to access polymorphic functions via an instance of a class. They're c=
alled virtual functions. So what would this "virtual static member function=
" actually do?<br></div></div></blockquote><div><br></div><div>The implemen=
tation (in terms of virtual static data members) would be exactly:</div><di=
v><br></div><div style=3D"background-color:rgb(250,250,250);border:1px soli=
d rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"color:rg=
b(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> </span><span styl=
e=3D"color:rgb(102,0,102)">Animal</span><span style=3D"color:rgb(0,0,0)"> <=
/span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb=
(0,0,0)"><br> </span><span style=3D"color:rgb(0,0,136)">static=
</span><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb=
(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><span=
style=3D"color:rgb(0,0,0)"> scientific_name</span><span style=3D"color:rgb=
(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">int</span><span sty=
le=3D"color:rgb(0,0,0)"> levels</span><span style=3D"color:rgb(102,102,0)">=
)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(1=
02,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"=
color:rgb(102,102,0)">...</span><span style=3D"color:rgb(0,0,0)"> </span><s=
pan style=3D"color:rgb(102,102,0)">}</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(136,0,0)">// a non-virtual static m=
ethod</span><span style=3D"color:rgb(0,0,0)"><br> </span><span=
style=3D"color:rgb(0,0,136)">virtual</span><span style=3D"color:rgb(0,0,0)=
"> </span><span style=3D"color:rgb(0,0,136)">static</span><span style=3D"co=
lor:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">constexpr</span>=
<span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,10=
2,0)">::</span><span style=3D"color:rgb(0,0,136)">string</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">(*</span=
><span style=3D"color:rgb(0,0,0)">pscientific_name</span><span style=3D"col=
or:rgb(102,102,0)">)(</span><span style=3D"color:rgb(0,0,136)">int</span><s=
pan style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"colo=
r:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">&</span><spa=
n style=3D"color:rgb(0,0,0)">scientific_name</span><span style=3D"color:rgb=
(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"> </span><span s=
tyle=3D"color:rgb(136,0,0)">// a virtual static data member</span><span sty=
le=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};<=
/span><span style=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"color:=
rgb(0,0,136)">void</span><span style=3D"color:rgb(0,0,0)"> print_name</span=
><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(102,=
0,102)">Animal</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0)">a</span>=
<span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"colo=
r:rgb(0,0,0)"> kpcofgs</span><span style=3D"color:rgb(102,102,0)">)</span><=
span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)=
">{</span><span style=3D"color:rgb(0,0,0)"><br> std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">=
cout </span><span style=3D"color:rgb(102,102,0)"><<</span><span style=
=3D"color:rgb(0,0,0)"> a</span><span style=3D"color:rgb(102,102,0)">-></=
span><span style=3D"color:rgb(0,0,0)">pscientific_name</span><span style=3D=
"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">kpcofgs</sp=
an><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,=
0,0)"> </span><span style=3D"color:rgb(102,102,0)"><<</span><span sty=
le=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::<=
/span><span style=3D"color:rgb(0,0,0)">endl</span><span style=3D"color:rgb(=
102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></span><span style=
=3D"color:rgb(102,102,0)">};</span></div></code></div><div><br></div><div>e=
xcept that we would add syntactic sugar so that it could be written as:</di=
v><div><br></div><div style=3D"background-color:rgb(250,250,250);border:1px=
solid rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"col=
or:rgb(0,0,136)">class</span><span style=3D"color:rgb(0,0,0)"> </span><span=
style=3D"color:rgb(102,0,102)">Animal</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"colo=
r:rgb(0,0,0)"><br> </span><span style=3D"color:rgb(0,0,136)">v=
irtual</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(0,0,136)">static</span><span style=3D"color:rgb(0,0,0)"> std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)=
">string</span><span style=3D"color:rgb(0,0,0)"> scientific_name</span><spa=
n style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)"=
>int</span><span style=3D"color:rgb(0,0,0)"> levels</span><span style=3D"co=
lor:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </span><span =
style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(102,102,0)">...</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">}</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(136,0,0)">// a=
virtual static method</span><span style=3D"color:rgb(0,0,0)"><br></span><s=
pan style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0,0,0)=
"><br><br></span><span style=3D"color:rgb(0,0,136)">void</span><span style=
=3D"color:rgb(0,0,0)"> print_name</span><span style=3D"color:rgb(102,102,0)=
">(</span><span style=3D"color:rgb(102,0,102)">Animal</span><span style=3D"=
color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">*</span><spa=
n style=3D"color:rgb(0,0,0)">a</span><span style=3D"color:rgb(102,102,0)">,=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,=
0,136)">int</span><span style=3D"color:rgb(0,0,0)"> kpcofgs</span><span sty=
le=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </spa=
n><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0=
,0)"><br> std</span><span style=3D"color:rgb(102,102,0)">::</s=
pan><span style=3D"color:rgb(0,0,0)">cout </span><span style=3D"color:rgb(1=
02,102,0)"><<</span><span style=3D"color:rgb(0,0,0)"> a</span><span s=
tyle=3D"color:rgb(102,102,0)">-></span><span style=3D"color:rgb(0,0,0)">=
scientific_name</span><span style=3D"color:rgb(102,102,0)">(</span><span st=
yle=3D"color:rgb(0,0,0)">kpcofgs</span><span style=3D"color:rgb(102,102,0)"=
>)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(=
102,102,0)"><<</span><span style=3D"color:rgb(0,0,0)"> std</span><spa=
n style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,0)">=
endl</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"colo=
r:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};</span></di=
v></code></div><div><div><br></div></div><div>The efficiency advantage over=
non-static virtual methods should be obvious at this point, but, for the c=
asual audience:<br></div><div>- No implicit *this pointer (reducing registe=
r pressure)</div><div>- Corollary to the above: no thunks or this-pointer a=
djustments needed</div><div>- Enforcement that no child class can ever (ab)=
use *this inside their implementation of scientific_name</div><div>- Symmet=
ry with non-static virtual methods</div></div></blockquote></span><div><br>=
So it's one advantage that you're counting three times (the fact that the f=
unction doesn't take a `this` pointer).<br></div></div></blockquote><div><b=
r></div><div>Two efficiency advantages (no register pressure and no need fo=
r fixup) and one semantic issue (enforcement of a constraint on all derived=
classes) that would be considered an advantage by one audience but perhaps=
not by others.</div><div> </div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-=
left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div =
dir=3D"ltr"><div>I don't buy the notion that this reduces register pressure=
.. Why? Because `this` already has to be in a register. Remember: this is a =
polymorphic dispatch. So you need to use `this` to access the vtable or wha=
tever other data structure the implementation uses to store virtual functio=
ns. So you already have a `this` at the call cite, thus you've had to reser=
ve a register for both it and the vtable. The only register pressure that c=
ould still be reduced is in the actual function call itself, and really, th=
at's getting into micro-optimization territory.<br><br>After all, it's stil=
l a virtual dispatch. The time you spent loading that vtable and getting th=
e function pointer out of it hurts far more than any register pressure.<br>=
</div></div></blockquote><div><br></div><div>You can't complain about "micr=
o-optimization territory" and then turn around and complain about the cost =
of a single memory access. :) You have to pick one side or the other.=
</div></div></div></div></blockquote><div><br>Sure I can:<br><br>1) It's a =
micro-optimization and therefore a rounding error in terms of performance.<=
br><br>2) Even if you consider micro-optimizations relevant for performance=
, it's still dwarfed by the memory access. So it's a micro-optimization of =
a micro-optimization.<br> </div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div> I'm coming do=
wn on the side of micro-optimization: C++ shouldn't allow any space between=
itself and the metal into which a better-designed language could sneak.&nb=
sp; C++ should <i>be</i> that better-designed language.</div></div></div></=
div></blockquote><div><br>That aphorism does not mean that C++ should allow=
you to do something just because it gives you more control. It doesn't mea=
n that C++ should give you ever micro-optimization possible (otherwise, we =
would have fixed the performance issues with dynamic_cast and typeid years =
ago. Not to mention the performance nightmare of iostream). It merely means=
that, all things being equal, C++ should provide you with meaningful low-l=
evel functionality.<br><br>If there is indeed some "space" between current =
virtual functions and static virtual functions... prove it. You can impleme=
nt virtual functions, both static and non-static, manually. So do so. Build=
a test application that actually gains some measurable improvement in perf=
ormance by moving from a non-static virtual function to a static one.<br>&n=
bsp;<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,2=
04,204);border-left-style:solid;padding-left:1ex"><div dir=3D"ltr"><span><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div>Nope; data members that are shared amo=
ng all instances of a class are properly described as "static".</div></div>=
</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-=
style:solid;padding-left:1ex"><div dir=3D"ltr"><div>The only data members t=
hat should ever be described as "non-static" are data members that are dupl=
icated by all instances of their class.</div></div></blockquote></span><div=
><br>That's one element of static data members, but there are many other el=
ements of them. Here's another: static data members can only be accessed th=
rough the type, not through an object instance.<br></div></div></blockquote=
><div><br></div><div>Aha, this might be the root cause of our disagreement!=
You'll be surprised to learn that static data members <i>can</i> be =
accessed through an object instance:</div></div></div></div></blockquote><d=
iv dir=3D"ltr"><br>I stand corrected.<div><div class=3D"gmail_quote"><div><=
br></div><div> </div><blockquote style=3D"margin: 0px 0px 0px 0.8ex; b=
order-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmai=
l_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-styl=
e:solid;padding-left:1ex"><div dir=3D"ltr"><div>That's why declaring that t=
hey're non-`static` but `constexpr` works. Since they are `constexpr`, they=
must be initialized at the class scope. So, if a `virtual constexpr` data =
member were actually stored within the class's instance, then every instanc=
e of the same class would get the same value.</div></div></blockquote><div>=
<br></div><div>s/class's instance/class definition/</div></blockquote></div=
></div></div><div><br>No, I meant exactly what I said.<br><br>If you think =
of `virtual constexpr` like non-static data members, then they would be per=
-instance data, stored in each object. But, since they're all `constexpr`, =
every instance would be storing the same value. Therefore, you could consid=
er centralizing the storage of such values as merely an optimization. Grant=
ed, the standard would enforce the "optimization", but the user could think=
of their "staticality" as the result of an enforced optimization, rather t=
han the whole purpose.<br><br>But the overall point is moot, since you can =
access static data members like non-static ones. And therefore, there's no =
confusion for accessing a static data member with an instance.<br></div></d=
iv>
<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_3750_1743294827.1431222269949--
------=_Part_3749_1995041102.1431222269948--
.
Author: David Krauss <potswa@mac.com>
Date: Sun, 10 May 2015 09:54:15 +0800
Raw View
--Apple-Mail=_99120394-F09C-48AE-8528-B59FAA25A1C1
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9305=E2=80=9310, at 7:19 AM, Arthur O'Dwyer <arthur.j.odwye=
r@gmail.com> wrote:
>=20
> I'm coming down on the side of micro-optimization: C++ shouldn't allow an=
y space between itself and the metal into which a better-designed language =
could sneak. C++ should be that better-designed language.
Note, the micro-optimization is still possible without any special support.=
Just define a virtual reference to the static function.
Covariance is lost vs. ordinary virtual functions, but that has overhead of=
its own. The point seems moot. And adding covariance to the mix brings sta=
tic virtual functions closer to classic virtual functions and further from =
virtual variables, which suggests that they go into a separate proposal.
--=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=_99120394-F09C-48AE-8528-B59FAA25A1C1
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=9305=
=E2=80=9310, at 7:19 AM, Arthur O'Dwyer <<a href=3D"mailto:arthur.j.odwy=
er@gmail.com" class=3D"">arthur.j.odwyer@gmail.com</a>> wrote:</div><br =
class=3D"Apple-interchange-newline"><div class=3D""><span style=3D"font-fam=
ily: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; =
font-weight: normal; letter-spacing: normal; line-height: normal; orphans: =
auto; text-align: start; text-indent: 0px; text-transform: none; white-spac=
e: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;=
float: none; display: inline !important;" class=3D"">I'm coming down on th=
e side of micro-optimization: C++ shouldn't allow any space between itself =
and the metal into which a better-designed language could sneak. C++ =
should<span class=3D"Apple-converted-space"> </span></span><i style=3D=
"font-family: Helvetica; font-size: 12px; font-variant: normal; font-weight=
: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-=
align: start; text-indent: 0px; text-transform: none; white-space: normal; =
widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D"=
">be</i><span style=3D"font-family: Helvetica; font-size: 12px; font-style:=
normal; font-variant: normal; font-weight: normal; letter-spacing: normal;=
line-height: normal; orphans: auto; text-align: start; text-indent: 0px; t=
ext-transform: none; white-space: normal; widows: auto; word-spacing: 0px; =
-webkit-text-stroke-width: 0px; float: none; display: inline !important;" c=
lass=3D""><span class=3D"Apple-converted-space"> </span>that better-de=
signed language.</span></div></blockquote></div><br class=3D""><div class=
=3D"">Note, the micro-optimization is still possible without any special su=
pport. Just define a virtual <i class=3D"">reference</i> to the static func=
tion.</div><div class=3D""><br class=3D""></div><div class=3D"">Covariance =
is lost vs. ordinary virtual functions, but that has overhead of its own. T=
he point seems moot. And adding covariance to the mix brings static virtual=
functions closer to classic virtual functions and further from virtual var=
iables, which suggests that they go into a separate proposal.</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=_99120394-F09C-48AE-8528-B59FAA25A1C1--
.