Применить функцию ко всем элементам в собственной матрице без цикла

У меня есть Eigen::Matrix, и я хотел бы создать новую матрицу, в которой все ее элементы генерируются некоторым вызовом функции для элементов матрицы:

Matrix< Foo,2,2 > m = ...;
Matrix< int, 2, 2> new_m;

for each m[i][j]:
  new_m[i][j] = m[i][j].member_of_foo_returns_int()

Я просмотрел Eigen::unaryExpr, но элементы изменились, и результат должен быть таким же. Однако у меня есть объекты Foo в первой матрице, а int возвращается в новой матрице. Возможно ли это без ванильного цикла?


person AspiringMat    schedule 26.05.2018    source источник


Ответы (1)


Вы можете передать лямбда-выражение в unaryExpr, например:

Eigen::Matrix<int,2,2> new_m = m.unaryExpr(
    [](const Foo& x) {
        return x.member_of_foo_returns_int();
    });

Если вы не можете использовать С++ 11, вам нужно написать небольшую вспомогательную функцию:

int func_wrapper(const Foo& x) {
    return x.member_of_foo_returns_int();
}

и передайте это, используя std::ptr_fun:

Eigen::Matrix<int,2,2> new_m = m.unaryExpr(std::ptr_fun(func_wrapper));

Для вызова функций-членов на самом деле уже реализована хорошая вспомогательная функция с именем std::mem_fun_ref (она принимает указатель на функцию-член и возвращает объект функтора, который принимается unaryExpr):

Eigen::Matrix<int,2,2> new_m = m.unaryExpr(
    std::mem_fun_ref(&Foo::member_of_foo_returns_int));

Все эти варианты типобезопасны, т. е. попытка сохранить результат в не-int-матрице не будет компилироваться.

person chtz    schedule 27.05.2018
comment
Благодарю вас! Принял ответ. - person AspiringMat; 27.05.2018