Ошибка компиляции Использование шаблонного программирования с библиотекой Eigen C ++

Я скачал библиотеку Eigen (3) и начал ее использовать. Я написал функцию шаблона и объявил локальную переменную типа шаблона внутри функции. Я получаю следующую ошибку компиляции.


$ g++ EigenTest.cpp

EigenTest.cpp: In instantiation of ‘void myFunc(Eigen::MatrixBase<Derived>&) [with Type1 = Eigen::Matrix<double, -1, -1>]’:
EigenTest.cpp:24:10:   required from here
EigenTest.cpp:16:26: error: conversion from ‘Eigen::DenseCoeffsBase<Eigen::Matrix<double, -1, -1>, 1>::Scalar {aka double}’ to non-scalar type ‘Eigen::Matrix<double, -1, -1>’ requested
Type1 tmp = matrix(0, 0);

«EigenTest.cpp» приведен ниже.


#include "Eigen/Dense"
#include <iostream>

template<typename Type1>
void myFunc(Eigen::MatrixBase<Type1>& matrix)
{
int i=matrix.rows();
Type1 tmp = matrix(0, 0);           // getting compiler error here
std::cout<<"tmp is ->"<<tmp<<std::endl;
}

int main()
{
Eigen::MatrixXd m(2,2);
m.setConstant(100);
myFunc(m);
return 0;
}

Я также пытался использовать ‘typename Type1 tmp = matrix (0, 0);’
Это тоже не сработало!

Как это исправить?
В обычном программировании шаблонов C ++ (без Eigen) я могу определить локальную переменную внутри функции шаблона как «Type1 tmp;»

1

Решение

В Eigen::MatrixBase<Type1>, Type1 это не скалярный тип, а тип фактического выражения. В вашем примере это будет MatrixXd, но если myFunc вызывается, например, m.block (…), то Type1 будет блок<…>. Чтобы получить скалярный тип, вы можете использовать Type1 :: Scalar:

template<typename Type1>
void myFunc(Eigen::MatrixBase<Type1>& matrix)
{
typename Type1::Scalar Scalar;
Scalar tmp = matrix(0, 0);
}

И если вам нужен тип матрицы, который похож на Type1использовать Type1::PlainObjectНапример:

typename Type1::PlainObject mat = 2 * matrix * matrix.transpose();
3

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

Это выглядит как MatrixBase использует «CRTP» (см. Вот), аргумент шаблона на самом деле является производным от него типом. Таким образом, в вашем использовании метода myFunc(), Type1 на самом деле представляет Eigen::MatrixXd, и я считать тот вы считать Type1 это двойной. Итак, эта строка:

Type1 tmp = matrix(0, 0);

В документе для этой библиотеки (см. Вот) typedef для MatrixXd является матрицей двойников, поэтому я думаю, что возвращение из matrix(0, 0) является двойным, и, как ТМП Type1 который Eigen::MatrixXdодно не войдет в другое.

Сканирование документов Я думаю, что для вашей функции лучше Matrix в качестве аргумента, таким образом, скалярный тип должен быть доступен. Что-то вроде этого:

template<class T, int rows, int cols, int opts, int maxR, int maxC >
void myFunc( Eigen::Matrix<T, rows, cols, opts, maxR, maxC>& matrix )
{
T tmp = matrix(0, 0);
}

(Выглядит ужасно, хотя !!! ;-))

1

В вашем коде Type1 выводится double (так как Eigen::MatrixXd определяется таким образом).

Вы тогда пытаетесь сделать

Type1 tmp = matrix(0, 0);

И я боюсь, что моих собственных знаний недостаточно, поэтому я запустил их через Clang 3.3 и получил эту ошибку:

test.cpp:9:7: error: no viable conversion from 'Scalar' (aka 'double') to
'Eigen::Matrix<double, -1, -1, 0, -1, -1>'
Type1 tmp = matrix(0, 0);           // getting compiler error here
^     ~~~~~~~~~~~~
test.cpp:17:1: note: in instantiation of function template specialization
'myFunc<Eigen::Matrix<double, -1, -1, 0, -1, -1> >' requested here
myFunc(m);
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:210:5: note: candidate constructor not viable:
no known conversion from 'Scalar' (aka 'double') to
'internal::constructor_without_unaligned_array_assert' for 1st argument
Matrix(internal::constructor_without_unaligned_array_assert)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:284:25: note: candidate constructor not
viable: no known conversion from 'Scalar' (aka 'double') to 'const
Eigen::Matrix<double, -1, -1, 0, -1, -1> &' for 1st argument
EIGEN_STRONG_INLINE Matrix(const Matrix& other)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:272:25: note: candidate template ignored:
could not match 'MatrixBase<type-parameter-0-0>' against 'double'
EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:292:25: note: candidate template ignored:
could not match 'ReturnByValue<type-parameter-0-0>' against 'double'
EIGEN_STRONG_INLINE Matrix(const ReturnByValue<OtherDerived>& other)
^
/usr/include/eigen3/Eigen/src/Core/Matrix.h:303:25: note: candidate template ignored:
could not match 'EigenBase<type-parameter-0-0>' against 'double'
EIGEN_STRONG_INLINE Matrix(const EigenBase<OtherDerived> &other)
^
1 error generated.

который говорит мне, что ты не можешь позвонить matrix так, с двумя 0 в качестве аргументов. Это также странный синтаксис, потому что MatrixBase класс не имеет operator() который вы, кажется, пытаетесь назвать.

0
По вопросам рекламы [email protected]