3

The code giving me an error is like below. And when I remove the "const" from the parameter type, it worked.

#include<iostream>
#include<vector>
#include</usr/include/eigen3/Eigen/Core>
using namespace std;

void func(const vector<double>& x)
{
  Eigen::VectorXd X=Eigen::Map<Eigen::VectorXd>(&x[0], x.size());
}

int main(){
  vector<double> x(100);
  func(x);
}

The error is like below. I can't understand it. Could anybody explain it to me? And is there a good way to do the same thing with "const" keyword?

error: invalid conversion from ‘const value_type* {aka const double*}’ to ‘Eigen::Map<Eigen::Matrix<double, -1, 1>, 0, Eigen::Stride<0, 0> >::PointerArgType {aka double*}’ [-fpermissive]
   Eigen::VectorXd X=Eigen::Map<Eigen::VectorXd>(&x[0], x.size());
orematasaburo
  • 1,207
  • 10
  • 20
  • 1
    the error message is clear, `&x[0]` is a `const double*` and your eigen function expect a `double *`, you can't convert from `const double*` to `double*` – Tyker Jun 25 '18 at 07:47
  • OK, here's the explanation. The `vector` argument `x` for `func` is passed as const reference: `const vector& x`, meaning that it can not be modified. When you map the internal data of `x` using `Eigen::Map` without indicating `const` in the template parameter, you are asking for a **non-const** conversion from a const reference. Such a conversion is not permitted by C++. So per ggael's suggestion, use either `Eigen::Map` or `Eigen::VectorXd::Map`. – Jonathan Lee Jun 25 '18 at 09:12
  • @Tyker Well you can, using `const_cast(&x[0])`, but that is usually not the right solution. – chtz Jun 25 '18 at 12:23
  • @chtz as you said it isn't a good solution. so don't want to advise it – Tyker Jun 25 '18 at 12:37

2 Answers2

5

Either use the static method VectorXd::Map to automatically infer constness:

Eigen::VectorXd X = Eigen::VectorXd::Map(x.data(), x.size());

or make it const explicitly:

Eigen::VectorXd X = Eigen::Map<const Eigen::VectorXd>(x.data(), x.size());

And instead of doing a deep copy within a VectorXd you might prefer to name the Map object to directly use it:

Eigen::Map<const Eigen::VectorXd> X(x.data(), x.size());
ggael
  • 28,425
  • 2
  • 65
  • 71
0

try this:

void func(vector<double>& x)
{
  Eigen::VectorXd X=Eigen::Map<Eigen::VectorXd>(x.data(), x.size());
}
Coral Kashri
  • 3,436
  • 2
  • 10
  • 22