【问题标题】:Wrong results using auto with Eigen使用带有 Eigen 的 auto 的错误结果
【发布时间】:2015-06-28 11:26:59
【问题描述】:

在对两个向量求和时,我使用 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 中的一个错误。

【问题讨论】:

  • 如果它听起来像“Eigen 和 C++11 中的一个错误”,它可能不是。再次仔细阅读文档,注意表达式模板。
  • 使用 eigen 3.2.2 对我来说成功。
  • 表达式模板和其他返回代理类型 (vector::operator[](size_t)) 的类在与 auto 一起使用时可能会令人惊讶。而不是得到你的向量的总和,你得到一个存储两个向量总和的表达式的类型。这是一个模板优化,通常用于大型对象实时矩阵。在其他新闻中,有一个关于“operator auto”的提议,它允许 Eigen 类作者在你的情况下返回一个实际的 Vector3。我知道 gcc,我认为 clang 已经把它偷偷溜进去了。也许破解你自己的“operator auto”然后看看。

标签: c++11 eigen


【解决方案1】:

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

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

foo(不要忘记包括&lt;typeinfo&gt;)。

在这种情况下,在构造了临时的Vector3 之后,会调用operator+ 方法,从而创建一个CwiseBinaryOp 对象。该对象是特征lazy evaluation 的一部分(可以提高性能)。如果您想强制进行急切评估(并因此确定类型),您可以使用

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

代替你在foo中的行。

一些旁注:

  • Vector3 与 Eigen 中定义的 Vector3d 类相同
  • 您可以使用 #include &lt;Eigen/Core&gt; 而不是 #include &lt;Eigen/Geometry&gt; 来包含大部分 Eigen 标头,以及应在此处定义的某些内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多