2016-03-18 3 views
3

Я хочу иметь рекурсивную функциюC++ Эйген: рекурсивные функции, принимающие любую матрицу класса

template <typename Derived> 
void f(Eigen::MatrixBase<Derived>& m) 
{ 
    size_t blockRows = ... 
    size_t blockCols = ... 
    .... 
    f(m.block(0, 0, blockRows, blockCols)); 
} 

К сожалению, это приводит к бесконечному времени компиляции рекурсии.

Первый вызов будет

f<Eigen::MatrixBase<Derived> > 

Второй будет

f<Eigen::Block<Eigen::MatrixBase<Derived>, ... > > 

Третий вызов будет

f<Eigen::Block<Eigen::Block<Eigen::MatrixBase<Derived>, ... >, ... > > 

Каждый раз, когда блок блока запрашивается ,

Какова наилучшая практика для реализации рекурсивных функций в Eigen, которые все еще работают с любым типом матрицы Eigen?

Я думаю, я должен использовать какой-то тип, который все еще обертывает одну и ту же часть памяти, но не является шаблоном выражения и оценивается.

ответ

2

Вы можете отдать свой рекурсивный блок к Eigen::Ref, чтобы избежать бесконечного типа экземпляра:

Ref<MatrixXd> bl = m.block(0, 0, blockRows, blockCols); 
f(bl); 

Чтобы оставаться полностью родовым, вы можете заменить MatrixXd на typename Derived::PlainObject.

+0

Я бы предположил, что вы используете PlainObjectBase, потому что нет PlainObjectType. Но это не работает. Я должен изменить подпись f на void f (Eigen :: Ref & m), чтобы она работала. Но потом она терпит неудачу с матрицами фиксированного размера. В этом случае m.block (..) имеет разные размеры из Derived. Таким образом, блок должен быть привязан к матрице, то же самое, что и Derived, но имеет динамический размер. – Sogartar

+0

Это 'PlainObject', а не' PlainObjectBase'. Я исправил ответ. – ggael