2017-09-05 27 views
2

Eigen :: Mapオブジェクトへのポインタを定義することは可能ですか?元のコードは、(擬似コード)は非常に複雑であるが、ここで私が達成しようとしているものです地図は基本的にすでにポインタであるので、それは更新して単純になるので、ここでポインタを使用するすべての不要のEigen :: Map <Eigen :: VectorXd>オブジェクトへのC++固有ポインタ

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のMapオブジェクトそれにもかかわらず、現在の設計では、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例:

例外はXを使用するときは、メモリを扱う VectorXd(または何かを返すようにtestFunction1を尋ねることによって、手動メモリ管理を回避する可能性が提起されている場合、それが漏れる可能性があるため、かなり悪いです
#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; 
} 

割り当て/割り当てを解除する)、メインの機能で新しい配置を行う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 else文が別の関数を必要とするため、読みにくくなりますが、他の人にとって役に立つかもしれないので、私はあなたの答えを受け入れます。しかし、私はまだマップへのポインタを宣言する方法が不思議です<...> – itQ

+0

'typedef const MapVectorXd ConstMapVectorXd;'を宣言してから 'ConstMapVectorXd *'を使用しますが、参照されるデータの両方に対して複雑な動的メモリ割り当てを扱わなければなりません新しいMapとMapオブジェクト自体によって、常にエラーやメモリリークが発生しやすくなります。 [placement new](https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html#title3)を使用してMapオブジェクト自体を変更すると、参照されるデータの割り当て/割り当て解除を「唯一」扱わなければならず、満足のいくものではない。 – ggael

+0

あなたの完全な答えは完璧です!巨大な感謝! – itQ

関連する問題