是否可以定义一个指向 Eigen::Map 对象的指针?原始代码非常复杂,但这是我要实现的(伪代码)
void testfunction1(... XPtr){
// XPtr is a pointer
// create a vector, map it to a Map object and make XPtr point to the latter
VectorXd Xnew(9);
Xnew << 10, 20, 30, 40, 50, 60, 70, 80, 90;
Map<VectorXd> XnewMap(Xnew.data(), 9);
// make XPtr point to XnewMap so that Xnew data can be
// accessed outside testfunction1()
// ... how? I suspect this to involve some dynamic memory allocation
};
void testfunction2(bool yes){
// main function
VectorXd XR(9);
XR << 1, 2, 3, 4, 5, 6, 7, 8, 9;
const Map<VectorXd> X(XR.data(), 9); // yes the mapped version is needed
// create a pointer to X, say XPtr
// ... how?
if(yes){ // make XPtr point to XnewMap which is defined in testfunction1()
testfunction1(XPtr);
};
//... some computations
// make XPtr point again to X
// ... how?
};
最佳答案
首先,这里不需要使用指针,因为 Map 本质上已经是一个指针,所以用 placement new 更新 Map 对象会更简单。 .尽管如此,您当前的设计将需要在 testfunction1 中进行分配,并在 testfunction2 中进行释放,以防它已被分配,这并不是很安全。因此,最好通过将“一些计算”放入函数(或命名的 lambda)中来采用函数式设计,使 testfunction1
按值返回:
VectorXd testFunction1() { return Xnew; }
void testfunction2(bool yes){
VectorXd XR(9);
XR << 1, 2, 3, 4, 5, 6, 7, 8, 9;
const Map<VectorXd> X(XR.data(), 9);
auto func = [&] (Eigen::Ref<VectorXd> X) {
/* some computation */
}
if(yes) func(testfunction1());
else func(X);
};
如果您真的想保留当前的逻辑,那么这里是一个使用 placement new 的独立示例:
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
void testfunction1(Map<VectorXd> &XMap){
double * Xnew = new double[9];
::new (&XMap) Map<VectorXd>(Xnew,9);
XMap << 10, 20, 30, 40, 50, 60, 70, 80, 90;
};
int main()
{
bool yes = true;
VectorXd XR(9);
XR << 1, 2, 3, 4, 5, 6, 7, 8, 9;
Map<VectorXd> X(XR.data(), 9);
if(yes) testfunction1(X);
// use X ...
cout << X.transpose() << endl;
// restore X and free memory allocated in testfunction1
if(yes){
delete[] X.data();
::new (&X) Map<VectorXd>(XR.data(),9);
}
cout << X.transpose() << endl;
}
这非常糟糕,因为如果在使用 X 时引发异常,它可能会泄漏。您可以通过要求 testFunction1 返回 VectorXd
来解决手动内存管理问题。 (或任何自行处理内存分配/释放的东西)并在主函数中进行新的放置:
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
VectorXd testfunction1(){
VectorXd Xnew(9);
Xnew << 10, 20, 30, 40, 50, 60, 70, 80, 90;
return Xnew;
};
int main()
{
bool yes = true;
VectorXd XR(9);
XR << 1, 2, 3, 4, 5, 6, 7, 8, 9;
Map<VectorXd> X(XR.data(), 9);
{
VectorXd X2;
if(yes) {
X2 = testfunction1(); // shallow copy thanks to move semantic
::new (&X) Map<VectorXd>(X2.data(),9);
}
// use X ...
cout << X.transpose() << endl;
// restore X
::new (&X) Map<VectorXd>(XR.data(),9);
}
cout << X.transpose() << endl;
}
最后,如果X
的内容应该是只读的,然后使用 Map<const VectorXd>
而不是 const Map<VectorXd>
正如您最初的问题。
关于指向 Eigen::Map<Eigen::VectorXd> 对象的 C++ 特征指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46060410/