为什么我不能在Eigen3中消除这个临时变量?

xjc*_*jcl 0 c++ eigen eigen3

我通过逐个矩阵乘法遇到了麻烦.即一个看起来很像的表达式总是返回一个接近[1 0]的向量,而一个看起来相似的表达式返回正确的结果:

// version WITH temp var, correct
Eigen::Vector3d lcoord_eig(lcoord[0], lcoord[1], lcoord[2]);
auto lcoord2d = P3to2 * lcoord_eig;
std::cout << std::endl << lcoord2d << std::endl;

// version WITHOUT temp var, always [1 0]
auto lcoord2d_2 = P3to2 * Eigen::Vector3d(lcoord[0], lcoord[1], lcoord[2]);
std::cout << std::endl << lcoord2d_2 << std::endl;
Run Code Online (Sandbox Code Playgroud)

where P3to2是2乘3矩阵(Eigen::MatrixXd)并且lcoord是其他库的3d矢量类型,上面的代码包含在for循环中.

一些输出(由我注释):

-0.0036135
2.1684e-18   // correct

1
0   // [1 0], wrong

0.00209583
0.000388139   // correct

1
5.55112e-17   // [1 0], wrong

0.00148429
-0.000435008   // correct

1
5.55112e-17   // [1 0], wrong
Run Code Online (Sandbox Code Playgroud)

这个错误花了我很长时间才发现,我仍然不明白发生了什么会导致第二个版本的行为像这样.我犯了什么错误?


编辑:这也适用于常量向量,例如 Eigen::Vector3d(.5,.5,.5)

Ala*_*kes 5

我的猜测(假设你没有在问题中包含足够的信息供任何人复制)是使用auto是你的问题.在你的第二个案例中,非工作的一个,我怀疑你留下了被摧毁的临时案件的悬空参考Vector3D.

单证说,"不使用具有本征的表情自动关键字,除非你是100%肯定,你在做什么".

如果您使用显式类型,您的程序将更清晰,更有可能工作.

  • @Sopel是的,Eigen确实使用了表达式模板,它可以在内部将临时绑定到`const`引用,并且该绑定在语句结束时不再有效.如果要强制求值,请在表达式的末尾使用`.eval();`,如`auto lcoord2d =(P3to2*lcoord_eig).eval();`.有关详细信息,请参阅[此链接](/sf/answers/2433340171/). (2认同)