错误地将自动类型说明符用于 Eigen 对象

Erroneous use of auto type specifier with Eigen objects

我有一个主要功能,如下所示:

#include <iostream>
#include <vector>
#include <Eigen/Dense>

using Eigen::Vector3d;
using namespace std;

void ext_func(vector<Vector3d> &a, vector<Vector3d> &b, vector<Vector3d> &c);
int main()
{
    vector<Vector3d> a = {};
    a.push_back(Vector3d(1.,1.,0.));
    a.push_back(Vector3d(2.,1.,0.));

    vector<Vector3d> b = {};
    b.push_back(Vector3d(.5,.7,2.));
    b.push_back(Vector3d(0.,.2,-1.2));

    vector<Vector3d> c = {};
    c.push_back(Vector3d::Zero());
    c.push_back(Vector3d::Zero());

    ext_func(a,b,c);

}

main开始,我调用了一个外部函数:

void ext_func(vector<Vector3d> &a, vector<Vector3d> &b, vector<Vector3d> &c)
{
    double fac = 0.01;
    for (size_t i = 0; i < a.size(); i++) {
        auto a_temp = a[i] + fac * b[i] / 50.;
        cout << "Before" << endl << fac*a_temp << endl;
        a[i] = a_temp;
        c[i] += fac*a_temp;
        cout << "After" << endl << fac*a_temp << endl << endl;
    }
}

输出为:

Before
 0.010001
0.0100014
    4e-06
After
 0.010002
0.0100028
    8e-06

Before
     0.02
0.0100004
 -2.4e-06
After
     0.02
0.0100008
 -4.8e-06

这不是我想要的(我希望 a_temp 在分配后保持不变)。我知道问题是我为 &a 分配了一个新值,所以当我调用 a_temp 时,我基本上是在第二次递增我的初始值 a[i]。将 auto 替换为 Vector3dVector3d&& 即可解决问题。

我不确定 auto 在这里真正做什么。

使用特征库中的矩阵进行计算时,重载运算符 return 表示计算表达式的对象。此表达式尚未计算(即尚未执行实际计算)。

在您的示例中,auto 派生的类型是 Eigen::CwiseBinaryOp<Eigen::internal::scalar_sum_op<double>, const Eigen::Matrix<double, 3, 1>, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_quotient1_op<double>, const Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<double>, const Eigen::Matrix<double, 3, 1>>>>

表达式的实际计算是在需要结果时完成的(例如,当分配给变量、打印等时)。

因为 a_temp 在你的例子中是表达式(不是结果),表达式被计算多次:

  • 当它作为 Before 行的一部分打印时
  • 分配给a[i]
  • 分配给c[i]
  • 当它作为 After 行的一部分打印时

其中第二个最终修改了表达式的操作数之一,因此表达式的后续计算将有不同的结果。