On 19 March 2017 at 21:10, Thiago Macieira <
thi...@macieira.org> wrote:
> On domingo, 19 de março de 2017 11:32:04 PDT Ville Voutilainen wrote:
>> On 19 March 2017 at 20:20, Thiago Macieira <
thi...@macieira.org> wrote:
>> >> Right, so this proposal doesn't produce UB. That leaves the other
>> >> compatibility issues.
>> >
>> > Which ones?
>>
>> See a couple of emails ago. The cases where the most-derived class
>> doesn't have access to the constructor
>> of the virtual base; that makes intentionally ill-formed cases well-formed.
>
> Right. This may have been used in existing code to limit inheritance in a tree
> to only classes that are explicitly white-listed as friends at some point.
>
> I'm wondering if now allowing this inheritance is a problem.
The technique appears in
http://www.stroustrup.com/bs_faq2.html#no-derivation
> And in this case, the author of the new class is simply saying "I'll have what
> he's having" (the direct base class that includes the virtual base). I
> understand that this technique would have been very useful to force a unique
> identifier per class in the hierarchy, but now we're allowing a derived class
> not to override the identifier (or silently forget to).
>
> Do we need a keyword to specifically allow this new functionality?
Grr. Let's not make it that complex. I think another interesting case is this:
#include <iostream>
struct B
{
B() {std::cout << "B default" << std::endl;}
B(int) {std::cout << "B int" << std::endl;}
};
struct D : virtual B
{
D() : B(42) {}
};
struct E : D
{
};
int main()
{
E e;
}
We presumably don't want to change how that behaves. So, in some
cases, E does initialize the virtual
base, in others, it doesn't. So, trying to keep that unchanged and the
no-derivation case working, we have something like
1) if default-initializing B from E is valid, we're done.
2) if default-initializing B from E fails due to access violation, we're done.
3) if default-initializing B from E fails due to overload resolution
failure for not finding a viable candidate,
don't initialize B in E but instead initialize E in D.
4) any existing explicit initialization of B from E is unchanged, and
there's no fallback to any base class.