Unwanted / unexpected compiler magic with native and ternary operator
The following code unexpectedly assigns (0, -1, 0) instead of (0, 1, 0) as intended. What for? Any ideas?
#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();
}
source to share
It happens to -unitZ
return the expression template const CwiseUnaryOp<internal::scalar_opposite_op<double>, const Vector3d>
if it unitZ
is Vector3d
. In earlier versions of Eigen, the "else" parameter of the operator ?:
received an implicit expression for this type and thus unwittingly negated it. This was banned a while ago by creating most of the constructors explicit
- so first of all you must update your version of Eigen.
For the actual solution: Avoid the statement ?:
with an Eigen expression (use a simple branch if-else
) or, if this is not possible, explicitly pass the last parameters to the type you want:
typedef Eigen::Vector3d Vec3d;
const Vec3d vect1 = useFirst ? Vec3d(-Vec3d::UnitZ()) : Vec3d(Vec3d::UnitY());
Related question: Type error in ternary operator in Eigen
source to share