Я хочу написать функцию, которая может принимать:
- плотный массив / матрица или
- транспонирование плотного массива / матрицы.
Можно ли избежать идеальной пересылки?
Я пытался использовать DenseBase
аргумент типа. Но это не может принять транспонирование матрицы.
Мне не нравится использовать идеальную пересылку, потому что реализация проверки типов с помощью sfinae была бы утомительной.
Текущее решение:
#include <Eigen/Eigen>
#include <iostream>
using namespace Eigen;
template <typename U>
auto f(U&& x) {
auto x2 = std::forward<U>(x);
auto max_x = x2.colwise().maxCoeff().eval();
x2 = x2.rowwise() + max_x;
return max_x;
}
int main() {
Array<float, 3, 3> M1;
M1 << 1, 2, 3,
4, 5, 6,
7, 8, 9;
std::cout << M1 << "\n";
// auto here might cause problem later ...
// see eigen.tuxfamily.org/dox/TopicPitfalls.html
auto max_x = f(M1.transpose());
std::cout << M1 << "\n";
std::cout << max_x << "\n";
}
Результат:
// original
1 2 3
4 5 6
7 8 9
// Increase each row by max of the row.
4 5 6
10 11 12
16 17 18
// Max of each row (not a column vector).
3 6 9
Я пробовал EigenBase
со следующими строками:
template <typename U>
auto f(EigenBase<U>& x) {
...
Ошибка компилятора:
test4.cpp:20:32: error: cannot bind non-const lvalue reference of type ‘Eigen::EigenBase<Eigen::Transpose<Eigen::Array<float, 3, 3> > >&’ to an rvalue of type ‘Eigen::EigenBase<Eigen::Transpose<Eigen::Array<float, 3, 3> > >’
auto max_x = f(M1.transpose());
~~~~~~~~~~~~^~