错误地将自动类型说明符用于 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
替换为 Vector3d
或 Vector3d&&
即可解决问题。
我不确定 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
行的一部分打印时
其中第二个最终修改了表达式的操作数之一,因此表达式的后续计算将有不同的结果。
我有一个主要功能,如下所示:
#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
替换为 Vector3d
或 Vector3d&&
即可解决问题。
我不确定 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
行的一部分打印时
其中第二个最终修改了表达式的操作数之一,因此表达式的后续计算将有不同的结果。