2017-05-23 2 views
3

Le code suivant attribue de manière inattendue (0, -1, 0) au lieu de (0, 1, 0) comme prévu. Pourquoi? Des idées?Compilateur-magie non désiré/inattendu avec opérateur propre et ternaire

#include <Eigen/Dense> 

int main() 
{ 
    const bool useFirst = false; 

    // This is the original use-case. 
    const Eigen::Vector3d vect1 
    = useFirst ? -Eigen::Vector3d::UnitZ() : Eigen::Vector3d::UnitY(); 

    // This version is somewhat simplified, but exhibits the same problem. 
    const Eigen::Vector3d unitZ(0.0, 0.0, 1.0), unitY(0.0, 1.0, 0.0); 
    const Eigen::Vector3d vect2 = useFirst ? -unitZ : unitY; 

    // FYI, this version does not compile (?). 
    // const Eigen::Vector3d vect3 
    // = useFirst ? -unitZ : Eigen::Vector3d::UnitY(); 
} 
+0

Sur mon ordinateur, la version 'vect1' ne compile pas mais la version' vect2' produit (0, 1, 0) comme prévu. – Cholts

Répondre

3

Qu'est-ce qui se passe est que -unitZ retourne un modèle d'expression const CwiseUnaryOp<internal::scalar_opposite_op<double>, const Vector3d>, si unitZ est un Vector3d. Dans les premières versions d'Eigen, le paramètre 'else' de l'opérateur ?: était implicitement casté à ce type et l'annulait donc involontairement. Cela a été interdit il y a un certain temps en faisant la plupart des constructeurs explicit - donc tout d'abord, vous devriez mettre à jour votre version Eigen.

Pour la solution réelle: éviter l'opérateur ?: avec des expressions Eigen (utiliser une simple branche if-else), ou en cas d'impossibilité, CAST explicitement les derniers paramètres du type souhaité:

typedef Eigen::Vector3d Vec3d; 
const Vec3d vect1 = useFirst ? Vec3d(-Vec3d::UnitZ()) : Vec3d(Vec3d::UnitY()); 

question connexe: Type error in ternary operator in Eigen

+0

Vous pouvez aussi '(...). Eval()' forcer l'évaluation du modèle d'expression. –