Topic: Not initializing virtual bases of abstract classes


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Thu, 18 Jul 2013 23:58:10 +0200
Raw View
--089e0158b4de8603a904e1d04f30
Content-Type: text/plain; charset=ISO-8859-1

Hello,

Currently, the following code is invalid:

    struct base {
        explicit base(some_complicated_type);
        virtual void foo() = 0; // base is abstract
        virtual ~base();
    };

    struct left : virtual base {};
    struct right : virtual base {};

    struct derived : left, right {
        derived() : base(some_complicated_function()) {}
        virtual void foo() override {}
    };

It is invalid, because left and right need to have a constructor that
initializes base. However, left and right are abstract classes anyway, so
they will never initialize their base themselves, since they inherit from
it virtually (and they are never instantiated directly, but only used as a
base to a derived class which then has the responsibility of initializing
the virtual base).

Currently, this requires rather stupid workarounds like:

    struct left : virtual base {
        left() : base(some_unused_dummy_value) {}
        // this dummy value won't ever be used, since 'left' is abstract.
    };
    // And simliar for right

Which can be worse than just a slight inconvenience when it is not trivial
to obtain a simple dummy value of some_complicated_type or base. (Which is
probably the case, since base doesn't have a default constructor.)

Also, when there are a lot of intermediate abstract classes, this
dummy-value-trick will have to be repeated all over the place.  A way worse
solution, but which at leasts prevent repeating would be to add a dummy
default constructor to base which should never be called:

    base() { /* Never call me! No seriously, bad things will happen. */ }

To prevent having to come up with a stupid and confusing workaround like
shown, I propose a minor change to the C++ standard:

    I propose to allow a derived class to not initialize a virtual base.
Doing so would simply make the derived class an abstract class.

-Maurice-

--

---
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/.



--089e0158b4de8603a904e1d04f30
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hello,<br><br>Currently, the following code is invalid:<br><br><span style=
=3D"font-family:courier new,monospace">=A0=A0=A0 struct base {<br>=A0=A0=A0=
 =A0=A0=A0 explicit base(some_complicated_type);<br>=A0=A0=A0 =A0=A0=A0 vir=
tual void foo() =3D 0; // base is abstract<br>

=A0=A0=A0 =A0=A0=A0 virtual ~base();<br>=A0=A0=A0 };<br><br>=A0=A0=A0 struc=
t left : virtual base {};<br>=A0=A0=A0 struct right : virtual base {};<br><=
br>=A0=A0=A0 struct derived : left, right {<br>=A0=A0=A0 =A0=A0=A0 derived(=
) : base(some_complicated_function()) {}</span><span style=3D"font-family:c=
ourier new,monospace"><span style=3D"font-family:courier new,monospace"><br=
>

=A0=A0=A0 =A0=A0=A0 virtual void foo() override {}</span><br>=A0=A0=A0 };</=
span><br><br>It is invalid, because left and right need to have a construct=
or that initializes base. However, left and right are abstract classes anyw=
ay, so they will never initialize their base themselves, since they inherit=
 from it virtually (and they are never instantiated directly, but only used=
 as a base to a derived class which then has the responsibility of initiali=
zing the virtual base).<br>

<br>Currently, this requires rather stupid workarounds like:<br><br><span s=
tyle=3D"font-family:courier new,monospace">=A0=A0=A0 struct left : virtual =
base {<br>=A0=A0=A0 =A0=A0=A0 left() : base(some_unused_dummy_value) {}<br>=
=A0=A0=A0 =A0=A0=A0 // this dummy value won&#39;t ever be used, since &#39;=
left&#39; is abstract.<br>

=A0=A0=A0 };<br>=A0=A0=A0 // And simliar for right</span><br><br>Which can =
be worse than just a slight inconvenience when it is not trivial to obtain =
a simple dummy value of some_complicated_type or base. (Which is probably t=
he case, since base doesn&#39;t have a default constructor.)<br>

<br>Also, when there are a lot of intermediate abstract classes, this dummy=
-value-trick will have to be repeated all over the place.=A0 A way worse so=
lution, but which at leasts prevent repeating would be to add a dummy defau=
lt constructor to base which should never be called:<br>

<br><span style=3D"font-family:courier new,monospace">=A0=A0=A0 base() { /*=
 Never call me! No seriously, bad things will happen. */ }</span><br><br>To=
 prevent having to come up with a stupid and confusing workaround like show=
n, I propose a minor change to the C++ standard:<br>

<br>=A0=A0=A0 I propose to allow a derived class to not initialize a virtua=
l base. Doing so would simply make the derived class an abstract class.<br>=
<br>-Maurice-<br>

<p></p>

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

--089e0158b4de8603a904e1d04f30--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 19 Jul 2013 01:54:13 +0300
Raw View
--047d7b6da616c87f0204e1d11647
Content-Type: text/plain; charset=ISO-8859-1

On 19 July 2013 00:58, Maurice Bos <m-ou.se@m-ou.se> wrote:

> Hello,
>
> Currently, the following code is invalid:
>
>     struct base {
>         explicit base(some_complicated_type);
>         virtual void foo() = 0; // base is abstract
>         virtual ~base();
>     };
>
>     struct left : virtual base {};
>     struct right : virtual base {};
>
>     struct derived : left, right {
>         derived() : base(some_complicated_function()) {}
>         virtual void foo() override {}
>     };
>
> It is invalid, because left and right need to have a constructor that
> initializes base. However, left and right are abstract classes anyway, so
> they will never initialize their base themselves, since they inherit from
> it virtually (and they are never instantiated directly, but only used as a
> base to a derived class which then has the responsibility of initializing
> the virtual base).
>

According to
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#257, that code
should
be valid.

--

---
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/.



--047d7b6da616c87f0204e1d11647
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 19 July 2013 00:58, Maurice Bos <span dir=3D"ltr">&lt;<a href=3D=
"mailto:m-ou.se@m-ou.se" target=3D"_blank">m-ou.se@m-ou.se</a>&gt;</span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br><br>Currently, =
the following code is invalid:<br><br><span style=3D"font-family:courier ne=
w,monospace">=A0=A0=A0 struct base {<br>
=A0=A0=A0 =A0=A0=A0 explicit base(some_complicated_type);<br>=A0=A0=A0 =A0=
=A0=A0 virtual void foo() =3D 0; // base is abstract<br>

=A0=A0=A0 =A0=A0=A0 virtual ~base();<br>=A0=A0=A0 };<br><br>=A0=A0=A0 struc=
t left : virtual base {};<br>=A0=A0=A0 struct right : virtual base {};<br><=
br>=A0=A0=A0 struct derived : left, right {<br>=A0=A0=A0 =A0=A0=A0 derived(=
) : base(some_complicated_function()) {}</span><span style=3D"font-family:c=
ourier new,monospace"><span style=3D"font-family:courier new,monospace"><br=
>


=A0=A0=A0 =A0=A0=A0 virtual void foo() override {}</span><br>=A0=A0=A0 };</=
span><br><br>It is invalid, because left and right need to have a construct=
or that initializes base. However, left and right are abstract classes anyw=
ay, so they will never initialize their base themselves, since they inherit=
 from it virtually (and they are never instantiated directly, but only used=
 as a base to a derived class which then has the responsibility of initiali=
zing the virtual base).<br>
</blockquote><div><br></div><div>According to <a href=3D"http://www.open-st=
d.org/jtc1/sc22/wg21/docs/cwg_defects.html#257">http://www.open-std.org/jtc=
1/sc22/wg21/docs/cwg_defects.html#257</a>, that code should<br>be valid.<br=
>
</div></div></div></div>

<p></p>

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

--047d7b6da616c87f0204e1d11647--

.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 03:26:06 -0700 (PDT)
Raw View
------=_Part_394_15092597.1374229566631
Content-Type: text/plain; charset=ISO-8859-1

I must've missed that. Thanks for pointing that out. (Both gcc and clang
won't compile the code, though. I filed a bug report for clang. Gcc already
had a bug report about it from 2005.)

There's a slight difference between what that defect discusses, and what I
tried to propose: When leaving out the line "virtual void foo() = 0;" such
that base isn't abstract, the code does become invalid now. It'd be
convenient if not only it is allowed to not initialize a virtual base in an
abstract class, but also that not initializing a virtual base would make
the class abstract. (Instead making the code ill-formed.)

-Maurice-

Op vrijdag 19 juli 2013 00:54:13 UTC+2 schreef Ville Voutilainen het
volgende:
>
>
>
>
> On 19 July 2013 00:58, Maurice Bos <m-o...@m-ou.se <javascript:>> wrote:
>
>> Hello,
>>
>> Currently, the following code is invalid:
>>
>>     struct base {
>>         explicit base(some_complicated_type);
>>         virtual void foo() = 0; // base is abstract
>>         virtual ~base();
>>     };
>>
>>     struct left : virtual base {};
>>     struct right : virtual base {};
>>
>>     struct derived : left, right {
>>         derived() : base(some_complicated_function()) {}
>>         virtual void foo() override {}
>>     };
>>
>> It is invalid, because left and right need to have a constructor that
>> initializes base. However, left and right are abstract classes anyway, so
>> they will never initialize their base themselves, since they inherit from
>> it virtually (and they are never instantiated directly, but only used as a
>> base to a derived class which then has the responsibility of initializing
>> the virtual base).
>>
>
> According to
> http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#257, that
> code should
> be valid.
>

--

---
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_394_15092597.1374229566631
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

I must've missed that. Thanks for pointing that out. (Both gcc and clang wo=
n't compile the code, though. I filed a bug report for clang. Gcc already h=
ad a bug report about it from 2005.)<br><br>There's a slight difference bet=
ween what that defect discusses, and what I tried to propose: When leaving =
out the line "virtual void foo() =3D 0;" such that base isn't abstract, the=
 code does become invalid now. It'd be convenient if not only it is allowed=
 to not initialize a virtual base in an abstract class, but also that not i=
nitializing a virtual base would make the class abstract. (Instead making t=
he code ill-formed.)<br><br>-Maurice-<br><br>Op vrijdag 19 juli 2013 00:54:=
13 UTC+2 schreef Ville Voutilainen het volgende:<blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><br><div><br><br><div class=3D"gmail_quo=
te">On 19 July 2013 00:58, Maurice Bos <span dir=3D"ltr">&lt;<a href=3D"jav=
ascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"uXeyGM3r0-4J">m-o...@m=
-ou.se</a>&gt;</span> wrote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex">Hello,<br><br>Currently, =
the following code is invalid:<br><br><span style=3D"font-family:courier ne=
w,monospace">&nbsp;&nbsp;&nbsp; struct base {<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; explicit base(some_complicated_type);=
<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; virtual void foo() =3D 0; // base=
 is abstract<br>

&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; virtual ~base();<br>&nbsp;&nbsp;&nbsp=
; };<br><br>&nbsp;&nbsp;&nbsp; struct left : virtual base {};<br>&nbsp;&nbs=
p;&nbsp; struct right : virtual base {};<br><br>&nbsp;&nbsp;&nbsp; struct d=
erived : left, right {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; derived() :=
 base(some_complicated_<wbr>function()) {}</span><span style=3D"font-family=
:courier new,monospace"><span style=3D"font-family:courier new,monospace"><=
br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; virtual void foo() override {}</span>=
<br>&nbsp;&nbsp;&nbsp; };</span><br><br>It is invalid, because left and rig=
ht need to have a constructor that initializes base. However, left and righ=
t are abstract classes anyway, so they will never initialize their base the=
mselves, since they inherit from it virtually (and they are never instantia=
ted directly, but only used as a base to a derived class which then has the=
 responsibility of initializing the virtual base).<br>
</blockquote><div><br></div><div>According to <a href=3D"http://www.open-st=
d.org/jtc1/sc22/wg21/docs/cwg_defects.html#257" target=3D"_blank">http://ww=
w.open-std.org/jtc1/<wbr>sc22/wg21/docs/cwg_defects.<wbr>html#257</a>, that=
 code should<br>be valid.<br>
</div></div></div></div>
</blockquote>

<p></p>

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

------=_Part_394_15092597.1374229566631--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 19 Jul 2013 18:09:36 +0300
Raw View
--047d7bb03d360e478304e1deb7fe
Content-Type: text/plain; charset=ISO-8859-1

On 19 July 2013 13:26, Maurice Bos <m-ou.se@m-ou.se> wrote:

> I must've missed that. Thanks for pointing that out. (Both gcc and clang
> won't compile the code, though. I filed a bug report for clang. Gcc already
> had a bug report about it from 2005.)
>

Do you have links for the bug reports? Chances are that I might be able to
do something about the gcc one.


>
> There's a slight difference between what that defect discusses, and what I
> tried to propose: When leaving out the line "virtual void foo() = 0;" such
> that base isn't abstract, the code does become invalid now. It'd be
> convenient if not only it is allowed to not initialize a virtual base in an
> abstract class, but also that not initializing a virtual base would make
> the class abstract. (Instead making the code ill-formed.)
>
>
Maybe. I have no trouble with the idea that default constructors of
abstract classes with virtual non-default-constructible
bases aren't deleted and that the initializers for the virtual bases aren't
necessary, but I'm not convinced turning a
class into an abstract one if it fails to initialize a virtual base is a
good idea. That sounds like papering over a design
bug, and how does it even work in cases where the derived class doesn't
even see the definitions of the base class
constructors?

--

---
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/.



--047d7bb03d360e478304e1deb7fe
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 19 July 2013 13:26, Maurice Bos <span dir=3D"ltr">&lt;<a href=3D=
"mailto:m-ou.se@m-ou.se" target=3D"_blank">m-ou.se@m-ou.se</a>&gt;</span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">I must&#39;ve missed that. Thanks for pointi=
ng that out. (Both gcc and clang won&#39;t compile the code, though. I file=
d a bug report for clang. Gcc already had a bug report about it from 2005.)=
<br>
</blockquote><div><br></div><div>Do you have links for the bug reports? Cha=
nces are that I might be able to do something about the gcc one.<br>=A0<br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">
<br>There&#39;s a slight difference between what that defect discusses, and=
 what I tried to propose: When leaving out the line &quot;virtual void foo(=
) =3D 0;&quot; such that base isn&#39;t abstract, the code does become inva=
lid now. It&#39;d be convenient if not only it is allowed to not initialize=
 a virtual base in an abstract class, but also that not initializing a virt=
ual base would make the class abstract. (Instead making the code ill-formed=
..)<br>
<br></blockquote><div><br></div><div>Maybe. I have no trouble with the idea=
 that default constructors of abstract classes with virtual non-default-con=
structible<br></div><div>bases aren&#39;t deleted and that the initializers=
 for the virtual bases aren&#39;t necessary, but I&#39;m not convinced turn=
ing a<br>
class into an abstract one if it fails to initialize a virtual base is a go=
od idea. That sounds like papering over a design<br>bug, and how does it ev=
en work in cases where the derived class doesn&#39;t even see the definitio=
ns of the base class<br>
constructors? <br></div></div><br></div></div>

<p></p>

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

--047d7bb03d360e478304e1deb7fe--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 19 Jul 2013 08:17:39 -0700
Raw View
--nextPart19101703.Qf7hg1THpU
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On sexta-feira, 19 de julho de 2013 03.26.06, Maurice Bos wrote:
> There's a slight difference between what that defect discusses, and what I
> tried to propose: When leaving out the line "virtual void foo() = 0;" such
> that base isn't abstract, the code does become invalid now. It'd be
> convenient if not only it is allowed to not initialize a virtual base in an
> abstract class, but also that not initializing a virtual base would make
> the class abstract. (Instead making the code ill-formed.)

You're asking to add a feature to not initialise the virtual base class(es),
which would make the class abstract, while currently we have the feature that
an abstract class doesn't have to initialise the virtual bases.

Why can't you use the feature we already have? Simply make any virtual
function pure. You must have at least one, don't you?

--
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

--nextPart19101703.Qf7hg1THpU
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBR6VifM/XwBW70U1gRAr8ZAKCOBLXhx8+haRZUVKfJFLWlQ378OgCfdFFn
BV2zknEY0fMMUyXXuJGZk1k=
=a+2R
-----END PGP SIGNATURE-----

--nextPart19101703.Qf7hg1THpU--


.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 17:56:17 +0200
Raw View
--089e013d1b9c25859904e1df5fb1
Content-Type: text/plain; charset=ISO-8859-1

2013/7/19 Ville Voutilainen <ville.voutilainen@gmail.com>

>
> On 19 July 2013 13:26, Maurice Bos <m-ou.se@m-ou.se> wrote:
>
>> I must've missed that. Thanks for pointing that out. (Both gcc and clang
>> won't compile the code, though. I filed a bug report for clang. Gcc already
>> had a bug report about it from 2005.)
>>
>
> Do you have links for the bug reports? Chances are that I might be able to
> do something about the gcc one.
>

Gcc: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19249 (Also see #29706.)
Clang: http://llvm.org/bugs/show_bug.cgi?id=16659



>
>
>>
>> There's a slight difference between what that defect discusses, and what
>> I tried to propose: When leaving out the line "virtual void foo() = 0;"
>> such that base isn't abstract, the code does become invalid now. It'd be
>> convenient if not only it is allowed to not initialize a virtual base in an
>> abstract class, but also that not initializing a virtual base would make
>> the class abstract. (Instead making the code ill-formed.)
>>
>>
> Maybe. I have no trouble with the idea that default constructors of
> abstract classes with virtual non-default-constructible
> bases aren't deleted and that the initializers for the virtual bases
> aren't necessary, but I'm not convinced turning a
> class into an abstract one if it fails to initialize a virtual base is a
> good idea. That sounds like papering over a design
> bug, and how does it even work in cases where the derived class doesn't
> even see the definitions of the base class
> constructors?
>

I guess I'm lacking some C++ knowledge, but I am not completely sure what
you mean with:
    "in cases where the derived class doesn't even see the definitions of
the base class constructors"
(Don't only the declarations matter? And those must be available since the
class definition must be available when using it as a base, right?)

The problem is that the only way to make a class abstract (such that
dummy-virtual-base-initialisation can be avoided), is to add a pure virtual
member function, if there isn't already one. (Example:
    struct A { explicit A(int); };
    struct B : virtual A { virtual void unused_dummy() = 0; };
    struct C : B { C() : A(37) {} void unused_dummy() override {} };
)

Another way this could be solved, is to allow some syntax to make a class
abstract, without it having a pure virtual member function. (Something like:
    struct A { explicit A(int); };
    struct B = 0 : virtual A {}; // Or whatever syntax makes sense.
    struct C : B { C() : A(37) {} };
)

--

---
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/.



--089e013d1b9c25859904e1df5fb1
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br><div class=3D"gmail_quote">2013/7/19 Ville Voutilainen <span dir=3D=
"ltr">&lt;<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">=
ville.voutilainen@gmail.com</a>&gt;</span><br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
">

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><div class=3D"gmail_quote">=
<div class=3D"im">On 19 July 2013 13:26, Maurice Bos <span dir=3D"ltr">&lt;=
<a href=3D"mailto:m-ou.se@m-ou.se" target=3D"_blank">m-ou.se@m-ou.se</a>&gt=
;</span> wrote:<br>


<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">I must&#39;ve missed that. Thanks for pointi=
ng that out. (Both gcc and clang won&#39;t compile the code, though. I file=
d a bug report for clang. Gcc already had a bug report about it from 2005.)=
<br>


</blockquote><div><br></div></div><div>Do you have links for the bug report=
s? Chances are that I might be able to do something about the gcc one.<br><=
/div></div></div></div></blockquote><div><br>Gcc: <a href=3D"http://gcc.gnu=
..org/bugzilla/show_bug.cgi?id=3D19249">http://gcc.gnu.org/bugzilla/show_bug=
..cgi?id=3D19249</a> (Also see #29706.)<br>

Clang: <a href=3D"http://llvm.org/bugs/show_bug.cgi?id=3D16659">http://llvm=
..org/bugs/show_bug.cgi?id=3D16659</a><br><br>=A0<br></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex">

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>=A0<br></div><div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>There&#39;s a slight difference between what that defect discusses, and=
 what I tried to propose: When leaving out the line &quot;virtual void foo(=
) =3D 0;&quot; such that base isn&#39;t abstract, the code does become inva=
lid now. It&#39;d be convenient if not only it is allowed to not initialize=
 a virtual base in an abstract class, but also that not initializing a virt=
ual base would make the class abstract. (Instead making the code ill-formed=
..)<br>


<br></blockquote><div><br></div></div><div>Maybe. I have no trouble with th=
e idea that default constructors of abstract classes with virtual non-defau=
lt-constructible<br></div><div>bases aren&#39;t deleted and that the initia=
lizers for the virtual bases aren&#39;t necessary, but I&#39;m not convince=
d turning a<br>


class into an abstract one if it fails to initialize a virtual base is a go=
od idea. That sounds like papering over a design<br>bug, and how does it ev=
en work in cases where the derived class doesn&#39;t even see the definitio=
ns of the base class<br>


constructors? <br></div></div></div></div></blockquote><div><br>I guess I&#=
39;m lacking some C++ knowledge, but I am not completely sure what you mean=
 with:<br>=A0=A0=A0 &quot;in cases where the derived class doesn&#39;t even=
 see the definitions of the base class constructors&quot;<br>

(Don&#39;t only the declarations matter? And those must be available since =
the class definition must be available when using it as a base, right?)<br>=
<br>The problem is that the only way to make a class abstract (such that du=
mmy-virtual-base-initialisation can be avoided), is to add a pure virtual m=
ember function, if there isn&#39;t already one. (Example:<span style=3D"fon=
t-family:courier new,monospace"><br>

=A0=A0=A0 struct A { explicit A(int); };<br>=A0=A0=A0 struct B : virtual A =
{ virtual void unused_dummy() =3D 0; };<br>=A0=A0=A0 struct C : B { C() : A=
(37) {} void unused_dummy() override {} };</span><br>)<br><br>Another way t=
his could be solved, is to allow some syntax to make a class
 abstract, without it having a pure virtual member function. (Something lik=
e:<br><span style=3D"font-family:courier new,monospace">=A0=A0=A0 struct A =
{ explicit A(int); };<br>=A0=A0=A0 struct B =3D 0 : virtual A {}; // Or wha=
tever syntax makes sense.<br>

=A0=A0=A0 struct C : B { C() : A(37) {} };</span><br>)<br>=A0</div></div><b=
r>

<p></p>

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

--089e013d1b9c25859904e1df5fb1--

.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 17:57:50 +0200
Raw View
--14dae93d9300be679c04e1df648d
Content-Type: text/plain; charset=ISO-8859-1

>
> Why can't you use the feature we already have? Simply make any virtual
> function pure. You must have at least one, don't you?
>

Well, I ran into a situation in which not all intermediate classes (those
which are never the most derived classes of any object I instantiate) are
abstract. However, they do inherit from a (virtual) base which is not
default constructible. To make use of the feature we already have, I'd have
not only have to add some dummy pure virtual member function, but also
provide an implementation for it in all of the most derived classes. (In
case you're interested, this is the class diagram (with simplified names):
http://random.m-ou.se/token.svg, only the gray ones are instantiated, the
rest could be abstract, but only part of it currently is.)

As I mentioned in my last e-mail (in reaction to Ville), a solution for
this would be to allow some syntax to make a class abstract, without having
to add a pure virtual member function.

--

---
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/.



--14dae93d9300be679c04e1df648d
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Why can&#39;t you use the feature we already have? Simply make any virtual<=
br>
function pure. You must have at least one, don&#39;t you?<br>
<span class=3D"HOEnZb"></span></blockquote><div><br>Well, I ran into a situ=
ation in which not all intermediate classes (those which are never the most=
 derived classes of any object I instantiate) are abstract. However, they d=
o inherit from a (virtual) base which is not default constructible. To make=
 use of the feature we already have, I&#39;d have not only have to add some=
 dummy pure virtual member function, but also provide an implementation for=
 it in all of the most derived classes. (In case you&#39;re interested, thi=
s is the class diagram (with simplified names): <a href=3D"http://random.m-=
ou.se/token.svg">http://random.m-ou.se/token.svg</a>, only the gray ones ar=
e instantiated, the rest could be abstract, but only part of it currently i=
s.)<br>

<br>As I mentioned in my last e-mail (in reaction to Ville), a solution for=
 this would be to allow some syntax to make a class abstract, without havin=
g to add a pure virtual member function.<br></div></div>

<p></p>

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

--14dae93d9300be679c04e1df648d--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 19 Jul 2013 09:16:46 -0700
Raw View
--nextPart2963974.jS3tMPSY1P
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On sexta-feira, 19 de julho de 2013 17.57.50, Maurice Bos wrote:
> > Why can't you use the feature we already have? Simply make any virtual
> > function pure. You must have at least one, don't you?
>
> Well, I ran into a situation in which not all intermediate classes (those
> which are never the most derived classes of any object I instantiate) are
> abstract. However, they do inherit from a (virtual) base which is not
> default constructible. To make use of the feature we already have, I'd have
> not only have to add some dummy pure virtual member function, but also
> provide an implementation for it in all of the most derived classes. (In
> case you're interested, this is the class diagram (with simplified names):
> http://random.m-ou.se/token.svg, only the gray ones are instantiated, the
> rest could be abstract, but only part of it currently is.)
>
> As I mentioned in my last e-mail (in reaction to Ville), a solution for
> this would be to allow some syntax to make a class abstract, without having
> to add a pure virtual member function.

I still don't see the problem. Why don't you make one of the virtuals that you
have become pure? That solves your problem.

You said that you have some intermediate classes that inherit the virtual
base, and yet you don't provide an explicit constructor initialisation for the
virtual base. Clearly, those intermediate classes cannot be instantiated.

If those classes can't be instantiated, why can't you make them abstract? Just
add "= 0" to any of the virtual methods that you must already have.

--
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

--nextPart2963974.jS3tMPSY1P
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBR6WZ0M/XwBW70U1gRAoqZAJ42CWpZBevyq3WnKROgzeGLKf2w3ACfRnU1
W403dsehRj8eyDicyCJuw8E=
=NaKw
-----END PGP SIGNATURE-----

--nextPart2963974.jS3tMPSY1P--


.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 18:38:18 +0200
Raw View
--001a11c3a9686892fa04e1dff538
Content-Type: text/plain; charset=ISO-8859-1

> I still don't see the problem. Why don't you make one of the virtuals that
> you
> have become pure? That solves your problem.
>
> You said that you have some intermediate classes that inherit the virtual
> base, and yet you don't provide an explicit constructor initialisation for
> the
> virtual base. Clearly, those intermediate classes cannot be instantiated.
>
> If those classes can't be instantiated, why can't you make them abstract?
> Just
> add "= 0" to any of the virtual methods that you must already have.
>
>
Consider this situation:

    struct A {
        explicit A(int);
        virtual void x() { foo(); }
    };
    struct B : virtual A {
        virtual void x() override { bar(); }
    };
    struct C1 : B { C1() : A(1) {} };
    struct C2 : B { C2() : A(2) {} };

Here, you can't 'just add "= 0"' without having to put the {bar();}
definition in both C1 and C2. However, either making B implicitly abstract
(because it doesn't initialise its virtual base A), or explicitly making it
abstract (using some new syntax) would solve the problem and make this code
valid.

(It's not that uncommon for a most derived class to not override any
(virtual) member functions. For example, in the bottom class of a classic
'diamond' inheritance structure.)

--

---
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/.



--001a11c3a9686892fa04e1dff538
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I still don&#=
39;t see the problem. Why don&#39;t you make one of the virtuals that you<b=
r>
have become pure? That solves your problem.<br>
<br>
You said that you have some intermediate classes that inherit the virtual<b=
r>
base, and yet you don&#39;t provide an explicit constructor initialisation =
for the<br>
virtual base. Clearly, those intermediate classes cannot be instantiated.<b=
r>
<br>
If those classes can&#39;t be instantiated, why can&#39;t you make them abs=
tract? Just<br>
add &quot;=3D 0&quot; to any of the virtual methods that you must already h=
ave.<br>
<div class=3D"HOEnZb"><div class=3D"h5"><br>
</div></div></blockquote></div><br>Consider this situation:<br><br><span st=
yle=3D"font-family:courier new,monospace">=A0=A0=A0 struct A {<br>=A0=A0=A0=
 =A0=A0=A0 explicit A(int);<br>=A0=A0=A0 =A0=A0=A0 virtual void x() { foo()=
; }<br>=A0=A0=A0 };<br>=A0=A0=A0 struct B : virtual A {<br>

=A0=A0=A0 =A0=A0=A0 virtual void x() override { bar(); }<br>=A0=A0=A0 };</s=
pan><span style=3D"font-family:courier new,monospace"><br>=A0=A0=A0 struct =
C1 : B { C1() : A(1) {} };</span><span style=3D"font-family:courier new,mon=
ospace"><br>=A0=A0=A0 struct C2 : B { C2() : A(2) {} };</span><br>

<br>Here, you can&#39;t &#39;just add &quot;=3D 0&quot;&#39; without having=
 to put the {bar();} definition in both C1 and C2. However, either making B=
 implicitly abstract (because it doesn&#39;t initialise its virtual base A)=
, or explicitly making it abstract (using some new syntax) would solve the =
problem and make this code valid.<br>

<br>(It&#39;s not that uncommon for a most derived class to not override an=
y (virtual) member functions. For example, in the bottom class of a classic=
 &#39;diamond&#39; inheritance structure.)<br>

<p></p>

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

--001a11c3a9686892fa04e1dff538--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 19 Jul 2013 19:39:56 +0300
Raw View
--001a113318ce11932404e1dffadc
Content-Type: text/plain; charset=ISO-8859-1

On 19 July 2013 18:56, Maurice Bos <m-ou.se@m-ou.se> wrote:

> Maybe. I have no trouble with the idea that default constructors of
> abstract classes with virtual non-default-constructible
>
>> bases aren't deleted and that the initializers for the virtual bases
>> aren't necessary, but I'm not convinced turning a
>> class into an abstract one if it fails to initialize a virtual base is a
>> good idea. That sounds like papering over a design
>> bug, and how does it even work in cases where the derived class doesn't
>> even see the definitions of the base class
>> constructors?
>>
>
> I guess I'm lacking some C++ knowledge, but I am not completely sure what
> you mean with:
>
>     "in cases where the derived class doesn't even see the definitions of
> the base class constructors"
> (Don't only the declarations matter? And those must be available since the
> class definition must be available when using it as a base, right?)
>
>
You can't see whether a constructor initializes a base if you look at the
declaration only. So,

struct B {};

struct D : virtual B
{
    D(); // abstract? How do we know that?
};

struct E : D
{
};

int main()
{
    E e; // if D is abstract, E is too, so we can't do this, but how can
anything but the linker know that?
}

Also, this would make D abstract even if it has no virtual functions
anywhere in the hierarchy.

This is a no-can-do.

--

---
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/.



--001a113318ce11932404e1dffadc
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><br><div class=3D"gmail=
_quote">On 19 July 2013 18:56, Maurice Bos <span dir=3D"ltr">&lt;<a href=3D=
"mailto:m-ou.se@m-ou.se" target=3D"_blank">m-ou.se@m-ou.se</a>&gt;</span> w=
rote:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">Maybe. I have no trouble with the idea that =
default constructors of abstract classes with virtual non-default-construct=
ible<br>
<div class=3D"gmail_quote"><div class=3D"im"><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><di=
v>bases aren&#39;t deleted and that the initializers for the virtual bases =
aren&#39;t necessary, but I&#39;m not convinced turning a<br>



class into an abstract one if it fails to initialize a virtual base is a go=
od idea. That sounds like papering over a design<br>bug, and how does it ev=
en work in cases where the derived class doesn&#39;t even see the definitio=
ns of the base class<br>



constructors? <br></div></div></div></div></blockquote></div><div><br>I gue=
ss I&#39;m lacking some C++ knowledge, but I am not completely sure what yo=
u mean with:<div class=3D"im"><br>=A0=A0=A0 &quot;in cases where the derive=
d class doesn&#39;t even see the definitions of the base class constructors=
&quot;<br>
</div>

(Don&#39;t only the declarations matter? And those must be available since =
the class definition must be available when using it as a base, right?)<br>=
<br></div></div></blockquote><div><br></div><div>You can&#39;t see whether =
a constructor initializes a base if you look at the declaration only. So,<b=
r>
<br></div><div>struct B {};<br><br></div><div>struct D : virtual B<br>{<br>=
</div><div>=A0=A0=A0 D(); // abstract? How do we know that?<br></div><div>}=
; <br><br></div><div>struct E : D<br>{<br>};<br><br></div><div>int main()<b=
r>
{<br></div><div>=A0=A0=A0 E e; // if D is abstract, E is too, so we can&#39=
;t do this, but how can anything but the linker know that?<br></div><div>}<=
br></div></div><br></div><div class=3D"gmail_extra">Also, this would make D=
 abstract even if it has no virtual functions anywhere in the hierarchy.<br=
>
<br>This is a no-can-do.<br></div></div>

<p></p>

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

--001a113318ce11932404e1dffadc--

.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 18:44:35 +0200
Raw View
--089e013d1b9ce3d81f04e1e00b67
Content-Type: text/plain; charset=ISO-8859-1

2013/7/19 Ville Voutilainen <ville.voutilainen@gmail.com>

>
> You can't see whether a constructor initializes a base if you look at the
> declaration only. So,
>
> struct B {};
>
> struct D : virtual B
> {
>     D(); // abstract? How do we know that?
> };
>
>
Ah, yes, now I get what you mean. Yes, then things will get very ugly
and/or impossible :)

What do you think about the other option I mentioned, a way to make a class
abstract without adding a pure virtual member function? (Something like
"struct X abstract {};" or "struct X = 0 {};" or some other syntax that
makes more sense.)

Now that A-B-C example I used before is only valid code if B is abstract,
but there is no way to make it abstract without introducing dummy code in
both B and all classes deriving from B.

--

---
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/.



--089e013d1b9ce3d81f04e1e00b67
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br><div class=3D"gmail_quote">2013/7/19 Ville Voutilainen <span dir=3D=
"ltr">&lt;<a href=3D"mailto:ville.voutilainen@gmail.com" target=3D"_blank">=
ville.voutilainen@gmail.com</a>&gt;</span><br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
">

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><div class=3D"gmail_quote">=
<div>You can&#39;t see whether a constructor initializes a base if you look=
 at the declaration only. So,<br>
<br></div><div>struct B {};<br><br></div><div>struct D : virtual B<br>{<br>=
</div><div>=A0=A0=A0 D(); // abstract? How do we know that?<br></div><div>}=
; <br><br></div></div></div></div></blockquote><div>=A0</div><div>Ah, yes, =
now I get what you mean. Yes, then things will get very ugly and/or impossi=
ble :)<br>

<br>What do you think about the other option I mentioned, a way to make a c=
lass abstract without adding a pure virtual member function? (Something lik=
e &quot;struct X abstract {};&quot; or &quot;struct X =3D 0 {};&quot; or so=
me other syntax that makes more sense.)<br>

<br>Now that A-B-C example I used before is only valid code if B is abstrac=
t, but there is no way to make it abstract without introducing dummy code i=
n both B and all classes deriving from B.<br></div></div><br>

<p></p>

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

--089e013d1b9ce3d81f04e1e00b67--

.


Author: Cassio Neri <cassio.neri@gmail.com>
Date: Fri, 19 Jul 2013 10:24:28 -0700 (PDT)
Raw View
------=_Part_518_13823954.1374254668392
Content-Type: text/plain; charset=ISO-8859-1



On Friday, July 19, 2013 5:44:35 PM UTC+1, Maurice Bos wrote:
>
>
> What do you think about the other option I mentioned, a way to make a
> class abstract without adding a pure virtual member function? (Something
> like "struct X abstract {};" or "struct X = 0 {};" or some other syntax
> that makes more sense.)
>
>

Suppose we have this syntax. Consider

struct A abstract {};
struct B : A {};

I guess, B would not be abstract. Is that right?

If so, You can already acomplish this behavior with very little boiler
plate code (no need to introduce a dummy pure virtual method). I tested
this works with GCC 4.8.1:

struct A {
    virtual inline ~A() = 0;
};
A::~A() = default;

Alternatively you can place the definition of ~A() in a cpp file and drop
the inline in the declaration.

HTH
Cassio.


--

---
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_518_13823954.1374254668392
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>On Friday, July 19, 2013 5:44:35 PM UTC+1, Maurice Bos wrote:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><div class=3D"gmail_quote"><div>=
What do you think about the other option I mentioned, a way to make a class=
 abstract without adding a pure virtual member function? (Something like "s=
truct X abstract {};" or "struct X =3D 0 {};" or some other syntax that mak=
es more sense.)<br>&nbsp;

<br></div></div></blockquote><div>&nbsp;<br>Suppose we have this syntax. Co=
nsider<br><br>struct A abstract {};<br>struct B : A {};<br><br>I guess, B w=
ould not be abstract. Is that right?<br><br>If so, You can already acomplis=
h this behavior with very little boiler plate code (no need to introduce a =
dummy pure virtual method). I tested this works with GCC 4.8.1:<br><br>stru=
ct A {<br>&nbsp;&nbsp;&nbsp; virtual inline ~A() =3D 0;<br>};<br>A::~A() =
=3D default;<br><br>Alternatively you can place the definition of ~A() in a=
 cpp file and drop the inline in the declaration.<br><br>HTH<br>Cassio.<br>=
<br><br></div>

<p></p>

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

------=_Part_518_13823954.1374254668392--

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Fri, 19 Jul 2013 12:25:24 -0500
Raw View
--001a11c3e0e40ca23f04e1e09f75
Content-Type: text/plain; charset=ISO-8859-1

On 19 July 2013 11:44, Maurice Bos <m-ou.se@m-ou.se> wrote:

>
> What do you think about the other option I mentioned, a way to make a
> class abstract without adding a pure virtual member function? (Something
> like "struct X abstract {};" or "struct X = 0 {};" or some other syntax
> that makes more sense.)
>

What's wrong with just having a protected destructor?
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

---
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/.



--001a11c3e0e40ca23f04e1e09f75
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

On 19 July 2013 11:44, Maurice Bos <span dir=3D"ltr">&lt;<a href=3D"mailto:=
m-ou.se@m-ou.se" target=3D"_blank">m-ou.se@m-ou.se</a>&gt;</span> wrote:<br=
><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<br><div class=3D"gmail_quote"><div>What do you think about the other optio=
n I mentioned, a way to make a class abstract without adding a pure virtual=
 member function? (Something like &quot;struct X abstract {};&quot; or &quo=
t;struct X =3D 0 {};&quot; or some other syntax that makes more sense.)<br>

</div></div></blockquote><div><br>What&#39;s wrong with just having a prote=
cted destructor?<br></div></div>-- <br>=A0Nevin &quot;:-)&quot; Liber=A0 &l=
t;mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D"_blank">nevin@=
eviloverlord.com</a>&gt;=A0 (847) 691-1404

<p></p>

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

--001a11c3e0e40ca23f04e1e09f75--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 19 Jul 2013 10:27:28 -0700
Raw View
--nextPart4363846.p6CZUrZjWW
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On sexta-feira, 19 de julho de 2013 18.38.18, Maurice Bos wrote:
> Consider this situation:
>
>     struct A {
>         explicit A(int);
>         virtual void x() { foo(); }
>     };
>     struct B : virtual A {
>         virtual void x() override { bar(); }
>     };
>     struct C1 : B { C1() : A(1) {} };
>     struct C2 : B { C2() : A(2) {} };
>
> Here, you can't 'just add "= 0"' without having to put the {bar();}
> definition in both C1 and C2.

Sure you can.

struct B: virtual A {
    virtual void x() override = 0;
};

// Bad practice to inline the only virtual method
inline void B::x()
{
    bar();
}


> However, either making B implicitly abstract
> (because it doesn't initialise its virtual base A), or explicitly making it
> abstract (using some new syntax) would solve the problem and make this code
> valid.

We don't need new syntax. We can use the existing syntax. That's what I've
been saying so far.

--
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

--nextPart4363846.p6CZUrZjWW
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBR6XcGM/XwBW70U1gRAisiAKC4brrAlEf0+5gKxvqmXLCSx7etVACcDbUb
YY0GSa/r2sPXU3f/5BrDyBw=
=t41t
-----END PGP SIGNATURE-----

--nextPart4363846.p6CZUrZjWW--


.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 20:19:38 +0200
Raw View
--089e0158b4ded86d0e04e1e15f98
Content-Type: text/plain; charset=ISO-8859-1

2013/7/19 Nevin Liber <nevin@eviloverlord.com>

>
> What's wrong with just having a protected destructor?
>
>
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#257 only talks
about abstract classes. Although a class with a protected destructor might
behave like an abstract class, it is not an abstract class.

Do you think that, in addition to the clarifications for abstract classes
that linked defect describes, similar additions can and should be made for
classes with protected destructors?

I don't think that's possible, because B having a protected destructor does
(strictly speaking) not prevent the construction of a B object other than
as a base, but only prevents the destruction of such an object.

--

---
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/.



--089e0158b4ded86d0e04e1e15f98
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

2013/7/19 Nevin Liber <span dir=3D"ltr">&lt;<a href=3D"mailto:nevin@evilove=
rlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;</span><br><div =
class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0=
 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div class=3D"gmail_quote"><div><br>What&#39;s wrong with just having a pro=
tected destructor?<span><font color=3D"#888888"><br></font></span></div></d=
iv><br></blockquote><div><br><a href=3D"http://www.open-std.org/jtc1/sc22/w=
g21/docs/cwg_defects.html#257" target=3D"_blank">http://www.open-std.org/jt=
c1/sc22/wg21/docs/cwg_defects.html#257</a> only talks about abstract classe=
s. Although a class with a protected destructor might behave like an abstra=
ct class, it is not an abstract class. <br>


<br>Do you think that, in addition to the clarifications for abstract class=
es that linked defect describes, similar additions can and should be made f=
or classes with protected destructors?<br><br>I don&#39;t think that&#39;s =
possible, because B having a protected destructor does (strictly speaking) =
not prevent the construction of a B object other than as a base, but only p=
revents the destruction of such an object.<br>

</div></div><br>

<p></p>

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

--089e0158b4ded86d0e04e1e15f98--

.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 20:20:05 +0200
Raw View
--001a11c341f077e57a04e1e161cd
Content-Type: text/plain; charset=ISO-8859-1

2013/7/19 Thiago Macieira <thiago@macieira.org>

> On sexta-feira, 19 de julho de 2013 18.38.18, Maurice Bos wrote:
> > Consider this situation:
> >
> >     struct A {
> >         explicit A(int);
> >         virtual void x() { foo(); }
> >     };
> >     struct B : virtual A {
> >         virtual void x() override { bar(); }
> >     };
> >     struct C1 : B { C1() : A(1) {} };
> >     struct C2 : B { C2() : A(2) {} };
> >
> > Here, you can't 'just add "= 0"' without having to put the {bar();}
> > definition in both C1 and C2.
>
> Sure you can.
>
> struct B: virtual A {
>     virtual void x() override = 0;
> };
>
> // Bad practice to inline the only virtual method
> inline void B::x()
> {
>     bar();
> }
>

No, that would make C1 and C2 abstract, right? Now you have to add an
override for x() in both C1 and C2, because otherwise they'll inherit the
pure member function from B which makes them abstract.

--

---
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/.



--001a11c341f077e57a04e1e161cd
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br><div class=3D"gmail_quote">2013/7/19 Thiago Macieira <span dir=3D"l=
tr">&lt;<a href=3D"mailto:thiago@macieira.org" target=3D"_blank">thiago@mac=
ieira.org</a>&gt;</span><br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div>On sexta-feira, 19 de julho de 2013 18.38.18, Maurice Bos wrote:<br>
&gt; Consider this situation:<br>
&gt;<br>
&gt; =A0 =A0 struct A {<br>
&gt; =A0 =A0 =A0 =A0 explicit A(int);<br>
&gt; =A0 =A0 =A0 =A0 virtual void x() { foo(); }<br>
&gt; =A0 =A0 };<br>
&gt; =A0 =A0 struct B : virtual A {<br>
&gt; =A0 =A0 =A0 =A0 virtual void x() override { bar(); }<br>
&gt; =A0 =A0 };<br>
&gt; =A0 =A0 struct C1 : B { C1() : A(1) {} };<br>
&gt; =A0 =A0 struct C2 : B { C2() : A(2) {} };<br>
&gt;<br>
&gt; Here, you can&#39;t &#39;just add &quot;=3D 0&quot;&#39; without havin=
g to put the {bar();}<br>
&gt; definition in both C1 and C2.<br>
<br>
</div>Sure you can.<br>
<br>
struct B: virtual A {<br>
=A0 =A0 virtual void x() override =3D 0;<br>
};<br>
<br>
// Bad practice to inline the only virtual method<br>
inline void B::x()<br>
{<br>
=A0 =A0 bar();<br>
<div>}<br></div></blockquote><div><br>No, that would make C1 and C2 abstrac=
t, right? Now you have to add an override for x() in both C1 and C2, becaus=
e otherwise they&#39;ll inherit the pure member function from B which makes=
 them abstract.<br>


</div><div>=A0</div></div>

<p></p>

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

--001a11c341f077e57a04e1e161cd--

.


Author: Maurice Bos <m-ou.se@m-ou.se>
Date: Fri, 19 Jul 2013 11:28:17 -0700 (PDT)
Raw View
------=_Part_390_13765841.1374258497770
Content-Type: text/plain; charset=ISO-8859-1



Op vrijdag 19 juli 2013 19:24:28 UTC+2 schreef Cassio Neri het volgende:
>
>
> struct A abstract {};
> struct B : A {};
>
> I guess, B would not be abstract. Is that right?
>

That is what I mean, indeed.


>
> If so, You can already acomplish this behavior with very little boiler
> plate code (no need to introduce a dummy pure virtual method). I tested
> this works with GCC 4.8.1:
>
> struct A {
>     virtual inline ~A() = 0;
> };
> A::~A() = default;
>

Nice.

That seems to solve the problem, indeed.

--

---
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_390_13765841.1374258497770
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<br><br>Op vrijdag 19 juli 2013 19:24:28 UTC+2 schreef Cassio Neri het volg=
ende:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><br><div>struct A abstrac=
t {};<br>struct B : A {};<br><br>I guess, B would not be abstract. Is that =
right?<br></div></blockquote><div><br>That is what I mean, indeed.<br>&nbsp=
;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>If so, You can=
 already acomplish this behavior with very little boiler plate code (no nee=
d to introduce a dummy pure virtual method). I tested this works with GCC 4=
..8.1:<br><br>struct A {<br>&nbsp;&nbsp;&nbsp; virtual inline ~A() =3D 0;<br=
>};<br>A::~A() =3D default;<br></div></blockquote><div><br>Nice.<br><br>Tha=
t seems to solve the problem, indeed.<br></div>

<p></p>

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

------=_Part_390_13765841.1374258497770--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Fri, 19 Jul 2013 12:40:08 -0700
Raw View
--nextPart5741034.mnyihdhF1u
Content-Transfer-Encoding: 7Bit
Content-Type: text/plain; charset="us-ascii"

On sexta-feira, 19 de julho de 2013 20.20.05, Maurice Bos wrote:
> 2013/7/19 Thiago Macieira <thiago@macieira.org>
> > Sure you can.
> >
> > struct B: virtual A {
> >
> >     virtual void x() override = 0;
> >
> > };
> >
> > // Bad practice to inline the only virtual method
> > inline void B::x()
> > {
> >
> >     bar();
> >
> > }
>
> No, that would make C1 and C2 abstract, right? Now you have to add an
> override for x() in both C1 and C2, because otherwise they'll inherit the
> pure member function from B which makes them abstract.

Right. Then you should make the destructor pure virtual.

--
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

--nextPart5741034.mnyihdhF1u
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: This is a digitally signed message part.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)

iD8DBQBR6ZYYM/XwBW70U1gRAl3oAJoDh9xoFOGnKbfvRX5M5RiCW0eVCACfY5TQ
EmTNQ3Tgv/8WDFMmfvmbcPQ=
=a6xq
-----END PGP SIGNATURE-----

--nextPart5741034.mnyihdhF1u--


.