Il problema non è con la conversione da uno o LeftSide
RightSide
a Side<T>
. Come inizialmente pensavi, questa conversione andrebbe bene.
Piuttosto, il problema è con questa espressione:
left < right ? new LeftSide<int> : new RightSide<int>
Rompiamo questo un po '. L'operatore ternario (propriamente di cui al standard come il 'operatore di confronto') si presenta così:
bool_val ? lhs_expression : rhs_expression
Tenete a mente che tutto questo costrutto è di per sé un'espressione. Significato restituisce un valore, che deve avere un tipo, obv. Il tipo di espressione intera viene dedotto dai tipi di lhs_expression
e rhs_expression
. In questo caso, hai un LeftSide
e un RightSide
. Quindi, ecco il tuo problema.
LeftSide
e RightSide
non sono direttamente correlati tra loro oltre che con una classe di base comune e non è disponibile alcuna conversione tra di essi. (Dovresti scriverne uno.) Quindi non esiste un singolo tipo di dati che lo bool_val ? lhs_expression : rhs_expression
possa avere. Potresti pensare, "beh, stupido compilatore, perché non capire solo la classe base comune e usarla?" Questo è, in effetti, un po 'di dolore. Lasciando da parte il fatto che sia giusto o sbagliato, non funziona in questo modo.
Hai due opzioni.
One, utilizzare un costrutto più semplice:
if(left < right)
return new LeftSide<int>;
else
return new RightSide<int>;
Due, se davvero vuole veramente utilizzare l'operatore ternario (che è il caso a volte), è necessario cucchiaio-alimentare il compilatore è tipi di dati:
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) Non è possibile scrivere le conversioni definite dall'utente tra i tipi di puntatore. (2) Devi solo correggere il tipo di un operando per farlo funzionare. (3) Anche 'static_cast' è eccessivo dato che esiste una conversione implicita e' static_cast' potrebbe impedire al compilatore di allertare sui legittimi problemi di sicurezza del tipo. –