Here is my example code:
(Please note the section surrounded by #if ENABLE_MY_COMPILE_ERROR
)
#include <Eigen/Core>
#include <iostream>
#define ENABLE_MY_COMPILE_ERROR 1
void f1(const Eigen::Ref<Eigen::MatrixXd> a,
const Eigen::Ref<Eigen::MatrixXd> b,
Eigen::Ref<Eigen::MatrixXd> c)
{
c = a * b;
}
int main(int argc, const char *argv[])
{
Eigen::Matrix3d M;
Eigen::Vector3d x;
Eigen::Vector3d y;
M.setRandom();
x.setRandom();
std::cout<<"M = \n"<<M<<std::endl;
std::cout<<"x = \n"<<x<<std::endl;
std::cout<<"M * x = \n"<<M * x<<std::endl;
{
y.setZero();
f1(M,x,y);
std::cout<<"y = \n"<<y<<std::endl;
}
{
Eigen::Matrix3d& MRef = M;
y.setZero();
f1(MRef,x,y);
std::cout<<"y = \n"<<y<<std::endl;
}
#if ENABLE_MY_COMPILE_ERROR
{
const Eigen::Matrix3d& MRef = M;
y.setZero();
f1(MRef,x,y);
std::cout<<"y = \n"<<y<<std::endl;
}
#endif
}
Here is the compile error I get when ENABLE_MY_COMPILE_ERROR != 0
:
In file included from ../../../../external/src/eigen-current/Eigen/Core:334:0,
from Eigen_Ref.C:1:
../../../../external/src/eigen-current/Eigen/src/Core/PlainObjectBase.h: In constructor ‘Eigen::Ref<PlainObjectType, Options, StrideType>::Ref(const Eigen::DenseBase<OtherDerived>&, typename Eigen::internal::enable_if<(bool)((Eigen::internal::is_lvalue<Derived>::value && (bool)(typename Eigen::internal::traits<Eigen::Ref<_PlainObjectType, _Options, _StrideType> >::match<Derived>::MatchAtCompileTime))), Derived>::type*, int) [with Derived = Eigen::Matrix<double, 3, 3>; PlainObjectType = Eigen::Matrix<double, -1, -1>; int Options = 0; StrideType = Eigen::OuterStride<>; typename Eigen::internal::enable_if<(bool)((Eigen::internal::is_lvalue<Derived>::value && (bool)(typename Eigen::internal::traits<Eigen::Ref<_PlainObjectType, _Options, _StrideType> >::match<Derived>::MatchAtCompileTime))), Derived>::type = Eigen::Matrix<double, 3, 3>]’:
../../../../external/src/eigen-current/Eigen/src/Core/PlainObjectBase.h:726:12: error: ‘Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3> >::<anonymous enum> Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3> >::ThisConstantIsPrivateInPlainObjectBase’ is private
Eigen_Ref.C:47:18: error: within this context
Thus, apparently the following are incompatible:
const Eigen::Ref<Eigen::MatrixXd> a
const Eigen::Matrix3d& MRef = M
My questions are:
Is this by design, or is this a bug/shortcoming of Eigen::Ref<>?
If by design, then what is a good way to cleanly pass around Matrix objects while preserving const correctness?
For example, if if have a class with a member function:
const Matrix3d& SomeClass::getTheSuperDuperMatrix() const
{
return this->superDuperMat;
}
and I plan on using this function's return value several times in a block of code, I'd like to create a reference to it with a short name and I'd like that to be a constant reference.
const Matrix3d& M = someClassInstance.getTheSuperDuperMatrix();
But then I will get the above compile error if I pass M into function which accepts a const Ref<Matrix3d>
argument, such as:
f1(M,x,y);
FYI, I am currently using the following version of Eigen:
Version: 3.2.91
Revision 5696:af94f93db432
This is because const Eigen::Ref<Eigen::MatrixXd>
is not a const reference. It must be declared like this:
Eigen::Ref<const Eigen::MatrixXd>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With