2015-05-20 3 views
2

У меня возникли проблемы с умножением двух матриц с использованием библиотеки Eigen. У меня есть следующая функция. Вот небольшой пример того, что я хотел бы сделать:Eigen C++ casting

Название программы: testMatOp.cpp

#include <iostream> 
#include <Eigen/Dense> 
using namespace std; 

template <typename DerivedA, typename DerivedB> 
void multiply(const Eigen::MatrixBase<DerivedA> &A, 
       const Eigen::ArrayBase<DerivedB> &B){ 
    Eigen::MatrixXf C(2,4); 
    C.array() = A.array().rowwise() * B.cast<float>(); 
} 

int main() 
{ 
    Eigen::MatrixXf A(2,4); 
    Eigen::MatrixXf C(2,4); 
    //igen::VectorXf v(4); 
    Eigen::Array<int,1,Eigen::Dynamic>B; 
    B.resize(4); 

    A << 1, 2, 6, 9, 
     3, 1, 7, 2; 

    B << 0, 
     1, 
     0, 
     0; 

    multiply(A,B); 
} 

Я хотел бы передать матрицу А и вектор В умножать. Я понимаю, что Eigen не выполняет автоматическое продвижение и что B нужно отливать как вектор с плавающей точкой, чтобы произошло размножение. Когда я компилирую, я получаю следующую ошибку компиляции среди других:

testMatOp.cpp:34:44: error: expected primary-expression before 'float' 
testMatOp.cpp:34:44: error: expected ';' before 'float' 
testMatOp.cpp: In instantiation of 'void multiply(const Eigen::MatrixBase<Derived>&, const Eigen::ArrayBase<DerivedB>&) [with DerivedA = Eigen::Matrix<float, -1, -1>; DerivedB = Eigen::Array<int, 1, -1>]': 
testMatOp.cpp:54:15: required from here 
testMatOp.cpp:34:3: error: no match for 'operator*' in '((const Eigen::DenseBase<Eigen::ArrayWrapper<const Eigen::Matrix<float, -1, -1> > >*)(&(& A)->Eigen::MatrixBase<Derived>::array<Eigen::Matrix<float, -1, -1> >()))->Eigen::DenseBase<Derived>::rowwise<Eigen::ArrayWrapper<const Eigen::Matrix<float, -1, -1> > >() * B.Eigen::ArrayBase<Derived>::cast<NewType>' 
testMatOp.cpp:34:3: note: candidates are: 
In file included from ../3rdparty/Eigen/Core:336:0, 
       from ../3rdparty/Eigen/Dense:1, 
       from testMatOp.cpp:26: 

Что я могу делать неправильно. Я посмотрел на этот пост: Cast Eigen::MatrixXd to Eigen::MatrixXf , который правильно описывает, как отливать, но я не могу заставить его работать для этого примера.

Любая помощь будет оценена по достоинству. Благодаря!

-a

ответ

4

Поскольку cast() функция состоит шаблон, в коде шаблона вы должны префикс с template ключевого слова:

B.template cast<float>(); 
2

B является dependent name. Для того, чтобы получить доступ к его члену шаблона cast, вы должны написать

B.template cast 

C++ является контекстно-зависимой. Когда встречается <, он пытается выяснить, есть ли это operator< или угловой кронштейн.

// std::vector is a template, so < is an angle bracket 
std::vector <float> 

// 3 is not a template, so < is operator< 
3 < 5 

Однако тип B является const Eigen::ArrayBase<DerivedB>&, которое зависит от параметра шаблона DerivedB. C++ не может решить, является ли B.cast шаблоном. Когда это происходит, C++ всегда угадывает, что это не шаблон и интерпретирует следующие < как operator<.

Почему C++ так глупый что он не может распознать ранее объявленный шаблон ArrayBase::cast? Ну, кто-то может специализироваться ArrayBase<int>.

template<> 
class ArrayBase<int> 
{ 
    public: 
    int cast = 3; 
}; 

Поэтому нельзя сделать вывод, что B.cast является шаблоном.