In this code:
template<class T>
struct Side
{
};
template<class T>
struct LeftSide : public Side<T>
{
};
template<class T>
struct RightSide : public Side<T>
{
};
Side<int>* f(int left, int right)
{
return left < right ? new LeftSide<int> : new RightSide<int>;//<---Here I'm returning either left or right side
}
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
I'm getting an error:
_Error 1 error C2446: ':' : no conversion from 'RightSide *' to 'LeftSide *'_
I've thought (wrongly as I see) that I can assign pointer from derived to base without any problems. So where is the problem?
The problem is not with the conversion from either LeftSide
or RightSide
to Side<T>
. As you originally thought, this conversion would be fine.
Rather, the problem is with this expression:
left < right ? new LeftSide<int> : new RightSide<int>
Let's break this down a little. The ternary operator (properly referred to in the Standard as the 'comparison operator') looks like this:
bool_val ? lhs_expression : rhs_expression
Keep in mind that this whole construct is itself an expression. Meaning it returns a value, which has to have a type, obv. The type of the whole expression is deduced from the types of lhs_expression
and rhs_expression
. In this case, you have a LeftSide
and a RightSide
. So, here's your problem.
LeftSide
and RightSide
are not directly related to each other other than having a common base class, and there's no conversion available between them. (You'd have to write one.) So there's no single datatype that the bool_val ? lhs_expression : rhs_expression
can have. You might think, "well, silly compiler, why not just figure out the common base class and use that?" This is, indeed, a bit of a pain. Leaving the argument of it being Right or Wrong aside, it just doesn't work that way.
You have two options.
One, use a simpler construct:
if( left < right )
return new LeftSide<int>;
else
return new RightSide<int>;
Two, if you really really want to use the ternary operator (which is the case sometimes), you need to spoon-feed the compiler it's datatypes:
Side<int>* f(int left, int right)
{
return left < right ? static_cast<Side<int>*>(new LeftSide<int>) : static_cast<Side<int>*>(new RightSide<int>);// now you're good
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With