This code:
bool contains = std::find(indexes.begin(), indexes.end(), i) != indexes.end();
CardAbility* cardAbility = contains ? new CardAbilityBurn(i) : new CardAbilityEmpty;
gives me the following error:
Incompatible operand types CardAbilityBurn and CardAbilityEmpty
However if I write the code like this:
if (contains)
{
cardAbility = new CardAbilityBurn(i);
}
else
{
cardAbility = new CardAbilityEmpty;
}
then the compiler doesn't mind. Why so? I want to use ternary conditional operator because it is just one line. What's wrong there?
I need to note (I think you might need this information) that CardAbilityEmpty
and CardAbilityBurn
both derive from CardAbility
so they are so to say brothers.
Thanks
There are several cases described for Microsoft compilers, how to handle operand types.
And then there is a caution:
Probably, this is the reason, Apple deactivated this implicit conversion in LLVM.
So, if/else seems to be more appropriate in your case.
C++'s type system determines expressions' types from the inside out[1]. That means that the conditional expression's type is determined before the assignment to
CardAbility*
is made, and the compiler has to choose with onlyCardAbilityBurn*
andCardAbilityEmpty*
.As C++ features multiple inheritance and some more possible conversion paths, since none of the types is a superclass of the other the compilation stops there.
To compile successfully, you need to provide the missing part : cast one or both operands to the base class type, so the conditional expression as a whole can take that type.
(Note the use of auto, since you already provided the destination type in the right-side expression.)
It is however a bit convoluted, so in the end the
if
-else
structure is better-suited in this case.[1] There is one exception : overloaded function names have no definitive type until you convert them (implicitly or explicitly) to one of their versions.