Обходной путь для Eigen :: Matrix для выпуска данных

Я хочу использовать 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 передать право собственности на свои данные (самостоятельно распределенные или принятые).

1

Решение

В nonCrasher2 с данными ничего не происходит, кроме того, что они были специально заполнены случайными значениями.

Тем не менее, это все еще выглядит как хакерский, и чистый подход заключается в использовании Map объект вместо MatrixXd:

Map<MatrixXd> m(data, dim, dim);
m.setRandom();

Если тебе надо m быть MatrixXd потому что вам нужно вызывать функции, принимающие MatrixXd объекты, и такие функции не могут быть шаблонными, то вы могли бы рассмотреть обобщение этих функций, чтобы взять Ref<MatrixXd> объекты. По умолчанию Ref<MatrixXd> может принять любое выражение, хранилище которого повторно собрать в MatrixXd с произвольным ведущим измерением. Это было введено в Eigen 3.2, проверьте документ для более подробной информации.

1

Другие решения

Других решений пока нет …