Le problème est pas avec la conversion de deux LeftSide
ou RightSide
à Side<T>
. Comme vous le pensiez à l'origine, cette conversion serait bien.
Au contraire, le problème est avec cette expression:
left < right ? new LeftSide<int> : new RightSide<int>
Brisons ce un peu. L'opérateur ternaire (correctement mentionné dans la norme comme « opérateur de comparaison ») ressemble à ceci:
bool_val ? lhs_expression : rhs_expression
Gardez à l'esprit que cette construction tout lui-même est une expression. Ce qui signifie qu'il renvoie une valeur, qui doit avoir un type, obv. Le type de l'expression entière est déduit des types lhs_expression
et rhs_expression
. Dans ce cas, vous avez un LeftSide
et un RightSide
. Alors, voici votre problème.
LeftSide
et RightSide
ne sont pas directement liés les uns aux autres autre que d'avoir une classe de base commune, et il n'y a pas de conversion disponible entre eux. (Vous devriez en écrire un.) Il n'y a donc pas de type de données unique que le bool_val ? lhs_expression : rhs_expression
peut avoir. Vous pourriez penser, "eh bien, compilateur stupide, pourquoi ne pas simplement comprendre la classe de base commune et l'utiliser?" C'est, en effet, un peu de douleur. En laissant de côté l'argument que c'est juste ou faux, cela ne fonctionne tout simplement pas de cette façon.
Vous avez deux options.
Un, utilisez une simple construction:
if(left < right)
return new LeftSide<int>;
else
return new RightSide<int>;
Deux, si vous voulez vraiment vraiment utiliser l'opérateur ternaire (ce qui est parfois le cas), vous devez cuillère nourrir le compilateur, il est des types de données:
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) Vous ne pouvez pas écrire des conversions définies par l'utilisateur entre les types de pointeurs. (2) Vous avez seulement besoin de fixer le type d'un opérande pour le faire fonctionner. (3) Même 'static_cast' est surchargé car une conversion implicite existe, et' static_cast' pourrait empêcher le compilateur d'avertir des problèmes légitimes de sécurité de type. –