指向 Eigen::Map<Eigen::VectorXd> 对象的 C++ 特征指针

标签 c++ pointers eigen dynamic-allocation

是否可以定义一个指向 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/

相关文章:

c++ - 将 shared_ptr 与通用注册表或共享对象存储一起使用......或不

使用函数指针从线程调用回调

c - malloc 没有正确分配 3d 数组

c++ - 使用 Eigen 创建具有俯仰、偏航、滚动的旋转矩阵

python - Tensorflow - Deep MNIST 教程 - 将分类器导出到 C++

c++ - 是否可以模板化 basic_string<>::iterator?

c++ - Netbeans C/C++ 多文件编译

c - 数组和指针的类比

c++ - 从 Eigen Matrix 继承并从内存构造或映射

c++ - 行式叉积特征值