使用 auto 和 Eigen 会得到错误的结果

问题描述 投票:0回答:2

在对两个向量求和时,使用 auto 和使用

Vector
得到了不同的结果。

我的代码:

#include "stdafx.h"
#include <iostream>
#include "D:\externals\eigen_3_1_2\include\Eigen\Geometry"

typedef Eigen::Matrix<double, 3, 1>       Vector3;

void foo(const Vector3& Ha, volatile int j) 
{
    const auto resAuto = Ha + Vector3(0.,0.,j * 2.567);
    const Vector3 resVector3 = Ha + Vector3(0.,0.,j * 2.567);

    std::cout << "resAuto = " << resAuto <<std::endl;
    std::cout << "resVector3 = " << resVector3 <<std::endl;
}

int main(int argc, _TCHAR* argv[])
{
    Vector3 Ha(-24.9536,-29.3876,65.801);
    Vector3 z(0.,0.,2.567);

    int j = 7;

    foo(Ha,j);
    return 0;
}

结果:

resAuto = -24.9536, -29.3876,65.801

resVector3 = -24.9536,-29.3876,83.77

按任意键继续。 。 .

我知道 Eigen 进行了内部优化,产生了不同的结果。但它看起来像是 Eigen 和 C++11 中的一个错误。

c++11 eigen
2个回答
5
投票

auto
关键字告诉编译器根据
=
的右侧“猜测”最佳对象。您可以通过添加来检查结果

std::cout << typeid(resAuto).name() <<std::endl;
std::cout << typeid(resVector3).name() <<std::endl;

foo
(不要忘记包括
<typeinfo>
)。

在这种情况下,在构造临时

Vector3
之后,调用
operator+
方法,该方法创建一个
CwiseBinaryOp
对象。该对象是特征惰性评估的一部分(可以提高性能)。如果你想强制急切求值(从而进行类型确定),你可以使用

const auto resAuto = (Ha + Vector3(0.,0.,j * 2.567)).eval();

而不是

foo
中的台词。

一些旁注:

  • Vector3
    与 Eigen
     中定义的 
    Vector3d
  • 类相同
  • 您可以使用
    #include <Eigen/Core>
    而不是
    #include <Eigen/Geometry>
    来包含大部分 Eigen 标头,以及应该在那里定义的某些内容。

0
投票

https://tmp.mosra.cz/eigen-docs/TopicPitfalls.html#TopicPitfalls_auto_keyword

关于 http://eigen.tuxfamily.org/ 的官方文档现已不可用,另请参阅 eigen/doc/Pitfalls.dox

Vector3(0.,0.,j * 2.567)
构造一个临时对象,然后由
Ha + Vector3(0.,0.,j * 2.567)
表达式引用。然而,这个临时对象在第一行之后就被删除了,然后
resAuto
表达式引用了一个死对象。

© www.soinside.com 2019 - 2024. All rights reserved.