Я хочу использовать Eigen3 для данных, поступающих из другой библиотеки. Ранее ответ Ггаэль указывает путь для Eigen::Matrix
принять существующие данные с new
ключевое слово. Однако для меня этого недостаточно, потому что Matrix
по-прежнему, кажется, приобретает право собственности на данные, а это означает, что он будет освобождать данные, выходя за рамки. Для этого это сбой, если data
в конце концов, удаляется из библиотеки, из которой:
void crasher(double* data, size_t dim)
{
MatrixXd m;
new (&m) Map<MatrixXd>(data,dim,dim); // matrix adopts the passed data
m.setRandom(); cout<<m<<endl; // manipulation of the passed data via the Matrix interface
} // data deleted by m => potential problem in scope of function call
Я придумал два обходных пути:
void nonCrasher1(double* data, size_t dim)
{
MatrixXd m; // semantically, a non-owning matrix
const Map<const MatrixXd> cache(m.data(),0,0); // cache the original „data” (in a const-correct way)
new (&m) Map<MatrixXd>(data,dim,dim); // matrix adopts the passed data
m.setRandom(); cout<<m<<endl; // manipulation of the passed data via the Matrix interface
new (&m) Map<const MatrixXd>(cache); // re-adopting the original data
} // original data deleted by m
Это довольно неудобно из-за наличия cache
, Другой свободен от этой проблемы:
void nonCrasher2(double* data, size_t dim) // no need for caching
{
MatrixXd m; // semantically, a non-owning matrix
new (&m) Map<MatrixXd>(data,dim,dim); // matrix adopts the passed data
m.setRandom(); cout<<m<<endl; // manipulation of the passed data via the Matrix interface
new (&m) Map<MatrixXd>(nullptr,0,0); // adopting nullptr for subsequent deletion
} // nullptr „deleted” by m (what happens with original data [if any]?)
Однако здесь неясно, что происходит с исходными данными m
(если есть — все это не совсем понятно из документации Eigen3).
У меня вопрос, есть ли канонический путь для Eigen::Matrix
передать право собственности на свои данные (самостоятельно распределенные или принятые).
В nonCrasher2
с данными ничего не происходит, кроме того, что они были специально заполнены случайными значениями.
Тем не менее, это все еще выглядит как хакерский, и чистый подход заключается в использовании Map
объект вместо MatrixXd
:
Map<MatrixXd> m(data, dim, dim);
m.setRandom();
Если тебе надо m
быть MatrixXd
потому что вам нужно вызывать функции, принимающие MatrixXd
объекты, и такие функции не могут быть шаблонными, то вы могли бы рассмотреть обобщение этих функций, чтобы взять Ref<MatrixXd>
объекты. По умолчанию Ref<MatrixXd>
может принять любое выражение, хранилище которого повторно собрать в MatrixXd
с произвольным ведущим измерением. Это было введено в Eigen 3.2, проверьте документ для более подробной информации.
Других решений пока нет …