C++ 使用本征和三元运算符的意外/意外编译器魔术

C++ 使用本征和三元运算符的意外/意外编译器魔术,c++,eigen,C++,Eigen,以下代码意外地指定(0,-1,0)而不是预期的(0,1,0)。为什么?有什么想法吗 #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

以下代码意外地指定(0,-1,0)而不是预期的(0,1,0)。为什么?有什么想法吗

#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();
}
#包括
int main()
{
const bool useFirst=false;
//这是最初的用例。
常量特征::矢量3D矢量1
=useFirst?-Eigen::Vector3d::UnitZ():Eigen::Vector3d::UnitY();
//这个版本有些简化,但也存在同样的问题。
常数本征::矢量三维单位Z(0.0,0.0,1.0),单位(0.0,1.0,0.0);
常量本征::向量3D vect2=useFirst?-unitZ:unitY;
//仅供参考,此版本不编译(?)。
//常量特征::矢量3D矢量3
//=useFirst?-unitZ:Eigen::Vector3d::UnitY();
}

如果
unitZ
是一个
Vector3d
,则
-unitZ
返回一个表达式模板
const CwiseUnaryOp
。在早期版本的Eigen中,
?:
操作符的'else'参数被隐式转换为该类型,因此非自愿地否定了它。这在不久前就被禁止了,因为大多数构造函数都是显式的,所以首先,你应该更新你的Eigen版本

对于实际的解决方案:避免使用本征表达式的
?:
运算符(使用简单的
if else
分支),或者如果不可能,将最后的参数显式转换为所需的类型:

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

相关问题:

在我的机器上,
vect1
版本不编译,但
vect2
版本会按预期生成(0,1,0)。您也可以
(…).eval()
强制计算表达式模板。