我想知道如何在Eigen中管理数据结构。
更确切地说,我想知道我是否应该将它们作为指针传递,或者它们实际上可能会使用一些智能指针。
例如,以下功能是否有意义:
SparseVector<double> retVector()
{
SparseVector<Double> vec(3);
return vec;
}
或者它会有问题,因为vec是一个局部变量,SparseVector不仅仅是vec周围的智能指针包装类吗?
意思是,或许最好使用:
SparseVector<double>* retVector()
{
SparseVector<Double> *vec = new SparseVector<double>(3);
return vec;
}
答案 0 :(得分:1)
比这更复杂。如果我们在讨论任何对象,@ Anycorn是正确的,因为未优化的版本将在返回时在函数中生成对象的深层副本。但是,启用优化后copy elision允许编译器在适当的位置构造返回的对象。这不是Eigen特有的。作为一个例子,我们可以看一个类似于你的函数返回一个特征对象。
Eigen::MatrixXd retMat()
{
Eigen::MatrixXd inMat = Eigen::MatrixXd::Random(1000,1000);
std::cout << &inMat << "\t" << inMat.data() << "\t" << *(inMat.data() + rand() * 20) << "\n";
return inMat;
}
Eigen::SparseMatrix<double> retSMat()
{
Eigen::MatrixXd denseMat = Eigen::MatrixXd::Random(100,100);
Eigen::SparseMatrix<double> inMat = denseMat.sparseView();
std::cout << &inMat << "\t" << "\n";
return inMat;
}
int main(int argc, char *argv[])
{
srand(time(NULL));
Eigen::MatrixXd outMat(5,5);
std::cout << "Dense matrix addresses (1):\n";
std::cout << &outMat << "\t" << outMat.data() << "\n";
outMat = retMat();
std::cout << &outMat << "\t" << outMat.data() << "\n\n";
std::cout << "Dense matrix addresses (2):\n";
Eigen::MatrixXd outMat2 = retMat();
std::cout << &outMat2 << "\t" << outMat2.data() << "\n\n";
std::cout << "Sparse matrix addresses:\n";
Eigen::SparseMatrix<double> outMatSp = retSMat();
std::cout << &outMatSp << "\n";
return 0;
}
在Debug中运行(关闭优化)我们得到:
Dense matrix addresses (1):
00000032B6A8EF58 00000032B6BDB870
00000032B6A8EEA8 00000032B6CDA070 -0.620289
00000032B6A8EF58 00000032B6CDD070
Dense matrix addresses (2):
00000032B6A8EEA8 00000032B7481070 0.157872
00000032B6A8EF88 00000032B7C3F070
Sparse matrix addresses:
00000032B6A8EE60
00000032B6A8EFC0
我们看到没有一个地址是相同的,正如对代码的天真解释所期望的那样。如果启用优化,则图片略有不同:
Dense matrix addresses (1):
0000009BEB0AF700 0000009BEB14BBF0
0000009BEB0AF780 0000009BEB2C1040 0.862606
0000009BEB0AF700 0000009BEBA7B040
Dense matrix addresses (2):
0000009BEB0AF718 0000009BEB2CC040 -0.601367
0000009BEB0AF718 0000009BEB2CC040
Sparse matrix addresses:
0000009BEB0AF740
0000009BEB0AF740
我们看到在情况(2)和稀疏矩阵示例中,对象的地址是相同的,表示对象是在目标对象地址中创建的。请注意,这与move semantics不同,后者需要书写move constructor(我很确定Eigen尚未实现)。
关于Eigen,由于它的lazy evaluation,一些表达式立即not evaluated,而是在被认为是谨慎/必要时。在简单示例中不是这种情况,但如果示例中有一些计算,则可以是这种情况。在这种情况下,返回的对象可能是在结果对象中追加/评估的表达式树。