Allowing a conversion to the base pointer type for the conditional operator sounds nice but would problematic in practice.
In your example
struct Base {};
struct Foo : Base {};
struct Bar : Base {};
It might seem like the obvious choice for the type of cond ? foo : bar
to be Base*
.
But that logic doesn't hold up for a general case
E.g.:
struct TheRealBase {};
struct Base : TheRealBase {};
struct Foo : Base {};
struct Bar : Base {};
Should cond ? foo : bar
be of type Base*
or of type TheRealBase*
?
How about:
struct Base1 {};
struct Base2 {};
struct Foo : Base1, Base2 {};
struct Bar : Base1, Base2 {};
What type should cond ? foo : bar
be now?
Or how about now:
struct Base {};
struct B1 : Base {};
struct B2 : Base {};
struct X {};
struct Foo : B1, X {};
struct Bar : B2, X {};
Base
/ \
/ \
/ \
B1 B2
| X |
| / \ |
|/ \ |
Foo Bar
Ouch!! Good luck reasoning for a type of cond ? foo : bar
. I know, ugly ugly, non-practical and being hunted worthy, but the standard would still have to have rules for this.
You get the point.
And also keep in mind that std::common_type
is defined in terms of the conditional operator rules.
Hm... These are excellent examples of situations that couldn't work, because of ambiguity. But C++ has many conversion rules that do work as long as the conversion is unambiguous. Like in this question. No?
Allowing just the unambiguous case here would be extremely problematic. The simple act of adding a base class could make the program uncompilable:
Initial codebase:
struct Base {};
struct Foo : Base {};
struct Bar : Base {};
This would allow __ ? foo : bar;
to be written. And now you can't modify the inheritance structure because almost any modification would break existing code that uses the ternary operator in a legitimate way:
struct FooBarCommon {};
struct Base {};
struct Foo : Base, FooBarCommon {};
struct Bar : Base, FooBarCommon {};
struct Baz : Base {};
This seems a reasonable modifications. As the rules are now you can do this as long as you don't modify the public API of your classes. This won't be true anymore the standard would allow the conversions to base class only in unambiguous cases.
6.3)
is the applicable rule, I believe? The rules that precede 6.3 all seem to fail to apply. – EpigrammatistBase* obj = !foo ? bar : foo;
If you get same error forbar
this time that means there is problem in compiler's logic. In such a condition you have to raise the question to vendor who has supplied you the compiler. I do not see any technical issue here. – FoxhoundFoo *
toBar *
and fali; tries a conversion fromBar *
toFoo *
and fail. Why should try a conversion of both toBase *
? And if there are more common bases, which pointer choose? – Dorolisavoid*
exists for both types, but we don't expect this conversion to actually fire, now do we? – Producer