简体   繁体   中英

Eigen c++ casting

I'm having trouble multiplying two matrices using the Eigen library. I have the following function. Here is a small example of what I would like to do :

Program name: 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);
}

I would like to pass Matrix A and Vector B to multiply. I understand that Eigen does not do automatic promotion and that B needs to be casted as a float vector in order for the multiplication to happen. When I compile, I get the following compilation error among others

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:

What might I be doing wrong. I did take a look at this post : Cast Eigen::MatrixXd to Eigen::MatrixXf which correctly describes how to cast, but I'm unable to make it work for this example.

Any help would be appreciated. Thanks!

-a

由于cast()是模板成员函数,因此在模板代码中,您必须在其前面加上template关键字:

B.template cast<float>();

B is a dependent name . To access its template member cast , you have to write

B.template cast

C++ is context-sensitive. When encountering a < , it tries to figure out if it is operator< or angle bracket.

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

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

However, the type of B is const Eigen::ArrayBase<DerivedB>& , which depends on the template parameter DerivedB . C++ cannot decide if B.cast is a template. When this happens, C++ always guess that it is not a template and interprets the following < as operator< .

Why C++ is so stupid that it cannot recognize previously declared template ArrayBase::cast ? Well, someone may specialize ArrayBase<int> .

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

Therefore one cannot deduce that B.cast is a template.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM