错误地将自动类型说明符与本征对象一起使用

我有一个主要功能如下:

#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.,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> &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在这里到底在做什么。

daihongze 回答:错误地将自动类型说明符与本征对象一起使用

在本征库中使用矩阵进行计算时,重载的运算符将返回一个代表计算表达式的对象。该表达式尚未求值(即尚未执行实际计算)。

在您的示例中,由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>,1>>>>

在需要结果时(例如,在分配变量,打印等时),将对表达式进行实际求值。

由于您使用的a_temp是表达式(而不是结果),因此该表达式会被多次求值:

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

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

本文链接:https://www.f2er.com/3064709.html

大家都在问