2017-09-05 758 views
2

是否可以定义指向特征:: Map对象的指针?原始代码是非常复杂,但这里是我想实现(伪代码)C++特征指针指向Eigen :: Map <Eigen :: VectorXd>对象

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? 

}; 

回答

0

所有没有必要在这里使用指针,因为地图是已经基本上是一个指针,所以它会更简单,从而更新第一与placement new的地图对象。尽管如此,当前的设计需要在testfunction1中进行分配,并且在testfunction2中进行了重新分配,以防其被分配,这并不安全。通过把“一些计算”功能内,以便更好地采用功能设计(或命名拉姆达),使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); 
}; 

如果你真的想保持当前的逻辑,那么这里是一个自使用放置新-contained例如:

#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; 
} 

这是非常不好的,因为如果一个异常被要求testFunction1返回一个VectorXd(或任何处理内存使用X时,你可以手动解决方法内存管理提出它可能会泄漏分配/取消分配)并在主函数中进行新的放置N:

#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>在你最初的问题。

+0

感谢您的回答。这是我当前的代码正在做的事情,但它使阅读变得困难,因为if语句需要不同的func,但我会接受你的答案,因为它可能对其他人有用。然而,我仍然想知道如何声明一个指向Map的指针<...> – itQ

+0

没有什么棘手的,只是声明'typedef const MapVectorXd ConstMapVectorXd;'然后使用'ConstMapVectorXd *',但是你必须处理复杂的动态内存分配通过新的Map和Map对象本身,这总是容易出错和内存泄漏。如果您使用[placement new](https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html#title3)修改Map对象本身,您将“仅”必须处理引用数据的分配/释放,更好,并不令人满意。 – ggael

+0

您的完整答案只是完美!非常感谢! – itQ