【问题标题】:Why are "const Eigen::Matrix<>&" and "const Ref<Eigen::Matrix<> >" apparently incompatible?为什么“const Eigen::Matrix<>&”和“const Ref<Eigen::Matrix<> >”显然不兼容?
【发布时间】:2013-12-11 01:14:27
【问题描述】:

这是我的示例代码:

(请注意#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
}

这是我在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

因此,显然以下内容是不兼容的:

  • const Eigen::Ref&lt;Eigen::MatrixXd&gt; a

  • const Eigen::Matrix3d&amp; MRef = M

我的问题是:

  • 这是设计使然,还是 Eigen::Ref 的错误/缺点?

  • 如果按照设计,那么在保持 const 正确性的同时干净地传递 Matrix 对象的好方法是什么?

例如,如果有一个带有成员函数的类:

const Matrix3d& SomeClass::getTheSuperDuperMatrix() const 
{
   return this->superDuperMat;
}

我打算在一段代码中多次使用这个函数的返回值,我想用一个短名称创建一个对它的引用,我希望它是一个常量引用。

const Matrix3d& M = someClassInstance.getTheSuperDuperMatrix();

但是如果我将 M 传递给接受const Ref&lt;Matrix3d&gt; 参数的函数,我会得到上述编译错误,例如:

f1(M,x,y);

仅供参考,我目前使用的是以下版本的 Eigen:

Version: 3.2.91
Revision 5696:af94f93db432

【问题讨论】:

    标签: c++ eigen eigen3


    【解决方案1】:

    这是因为 const Eigen::Ref&lt;Eigen::MatrixXd&gt; 不是 const 引用。必须这样声明:

    Eigen::Ref<const Eigen::MatrixXd>
    

    【讨论】:

    • 太棒了!谢谢你,盖尔!我很高兴答案是这样干净/简单。在文档(eigen.tuxfamily.org/dox-devel/…)中,我在Ref&lt;&gt; 之前看到了const,但我没有仔细阅读以看到const 在尖括号内重复出现。 (哎呀!)我指的是:void cov(const Ref&lt;const MatrixXf&gt; x, const Ref&lt;const MatrixXf&gt; y, Ref&lt;MatrixXf&gt; C)constRef&lt;&gt; 之前的意义是什么?什么时候使用?
    • 关于我关于领先 const 的后续问题,我认为答案类似于指向 constconst 指针与指向 const 的非常量指针。这个答案的详细信息:stackoverflow.com/questions/1143262
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多