tout d'abord pas besoin d'utiliser des pointeurs ici parce que la carte est déjà essentiellement un pointeur, il serait plus simple si la mise à jour l'objet Carte avec placement new. Néanmoins, votre conception actuelle nécessiterait une allocation dans testfunction1 et une allocation dans testfunction2 au cas où elle aurait été allouée, ce qui n'est pas vraiment sûr. Il vaudrait donc mieux adopter une conception fonctionnelle en mettant « certains calculs » dans une fonction (ou un lambda nommé), faire testfunction1
retour par valeur:
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);
};
Si vous voulez vraiment garder votre logique actuelle, alors voici une auto par exemple à l'aide -contained placement nouvelle:
#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;
}
ce qui est assez mauvais, car il peut fuir si une exception est levée lors de l'utilisation X. Vous pouvez contourner la gestion de la mémoire manuelle en demandant testFunction1 de retourner un VectorXd
(ou quoi que ce soit qui gèrent la mémoire allocation/désallocation en soi) et faire le placement nouveau dans la fonction principale 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;
}
Enfin, si le contenu de X
doit être en lecture seule, puis utilisez Map<const VectorXd>
et non const Map<VectorXd>
comme dans votre question initiale.
Merci pour votre réponse. C'est ce que fait mon code actuel, mais cela rend la lecture difficile car l'instruction if else nécessite une fonction différente, mais j'accepte votre réponse car elle peut être utile aux autres. Cependant, je me demande encore comment déclarer un pointeur sur Map <...> – itQ
Rien de compliqué, il suffit de déclarer 'typedef const MapVectorXd ConstMapVectorXd; 'puis d'utiliser' ConstMapVectorXd * ', mais vous devez gérer une allocation de mémoire dynamique complexe pour les données référencées par la nouvelle carte et l'objet Map lui-même, qui est toujours sujette à des erreurs et des fuites de mémoire. Si vous modifiez l'objet Map lui-même à l'aide de [placement new] (https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html#title3), vous devrez "seulement" gérer l'allocation/désallocation des données référencées, mieux, pas satisfaisant. – ggael
Votre réponse complète est juste PARFAIT! Merci beaucoup! – itQ