Das Problem ist nicht mit der Umwandlung von entweder LeftSide
oder RightSide
zu Side<T>
. Wie Sie ursprünglich dachten, wäre diese Umwandlung in Ordnung.
Vielmehr ist das Problem mit diesem Ausdruck:
left < right ? new LeftSide<int> : new RightSide<int>
ist dies ein wenig Lassen Sie brechen. Der ternäre Operator (richtig in Standard als ‚Vergleichsoperator‘ genannt) sieht wie folgt aus:
bool_val ? lhs_expression : rhs_expression
Beachten Sie, dass dieses ganze Konstrukt ist selbst ein Ausdruck. Das heißt, es gibt einen Wert zurück, der einen Typ haben muss, obv. Der Typ des ganzen Ausdrucks wird von den Typen lhs_expression
und rhs_expression
abgeleitet. In diesem Fall haben Sie eine LeftSide
und eine RightSide
. Also, hier ist dein Problem.
LeftSide
und RightSide
sind nicht direkt miteinander verwandt, außer eine gemeinsame Basisklasse zu haben, und es gibt keine Konvertierung zwischen ihnen. (Sie müssten einen schreiben.) Es gibt also keinen einzigen Datentyp, den bool_val ? lhs_expression : rhs_expression
haben kann. Du könntest denken: "Nun, dummer Compiler, warum nicht einfach die gemeinsame Basisklasse herausfinden und verwenden?" Das ist in der Tat ein bisschen Schmerz. Wenn man das Argument, dass es richtig oder falsch ist, beiseite lässt, funktioniert das einfach nicht so.
Sie haben zwei Möglichkeiten.
One, verwenden Sie ein einfacheres Konstrukt:
if(left < right)
return new LeftSide<int>;
else
return new RightSide<int>;
Zwei, wenn Sie wirklich den ternären Operator verwenden möchten wirklich (was der Fall ist manchmal), müssen Sie den Compiler es Datentypen gängeln:
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
}
(1) Sie können nicht benutzerdefinierte Konvertierungen zwischen Zeigertypen schreiben. (2) Sie müssen nur den Typ eines Operanden korrigieren, damit er funktioniert. (3) Sogar 'static_cast' ist Overkill, da eine implizite Konvertierung existiert, und' static_cast' könnte den Compiler daran hindern, über legitime Typsicherheitsprobleme zu warnen. –