将参数作为 Ref 类型推导传递

Passing Arguments as Ref type deduction

我的设置如下:

class Base
{
  public:
    virtual void eval(const Ref< const Matrix<float,Dynamic,1>> in, Ref<Matrix<float,Dynamic,1>> out) = 0;
    virtual void eval( const Ref< const Matrix<float,Dynamic,Dynamic,RowMajor>> inp, Ref<Matrix<float,Dynamic,Dynamic,RowMajor>> out) = 0;
};

class Test : Base
{
  public:
  void eval(const Ref< const Matrix<float,Dynamic,1>> in, Ref<Matrix<float,Dynamic,1>> out) override
  {
      out = in;
  };

void eval( const Ref< const Matrix<float,Dynamic,Dynamic,RowMajor>> in, Ref<Matrix<float,Dynamic,Dynamic,RowMajor>> out)override
{
    for(std::size_t i=0;i<in.rows();i++)
      eval( in.row(i).transpose(), out.row(i).transpose() );
};
};

编译器错误如下所示:

In file included from main.cc:2:0:
../tmp.hpp: In member function ‘virtual void eval(Eigen::Ref<const Eigen::Matrix<float, -1, -1, 1> >, Eigen::Ref<Eigen::Matrix<float, -1, -1, 1> >)’:
../tmp.hpp:36:62: error: call of overloaded ‘eval(Eigen::DenseBase<Eigen::Block<const Eigen::Ref<const Eigen::Matrix<float, -1, -1, 1> >, 1, -1, true> >::ConstTransposeReturnType, Eigen::Transpose<Eigen::Block<Eigen::Ref<Eigen::Matrix<float, -1, -1, 1> >, 1, -1, true> >)’ is ambiguous
    eval( in.row(i).transpose(), out.row(i).transpose() );
                                                              ^
../tmp.hpp:25:7: note: candidate: virtual void eval(Eigen::Ref<const Eigen::Matrix<float, -1, 1> >, Eigen::Ref<Eigen::Matrix<float, -1, 1> >)
  void eval(const Ref<const Matrix<float, Dynamic, 1>> input,
       ^
../tmp.hpp:32:7: note: candidate: virtual void eval(Eigen::Ref<const Eigen::Matrix<float, -1, -1, 1> >, Eigen::Ref<Eigen::Matrix<float, -1, -1, 1> >)
  void eval(const Ref<const Matrix<float, Dynamic, Dynamic, RowMajor>> input,
       ^
make: *** [main.o] Error 1

我找到了 this。类型不匹配,但对我来说,不清楚如何解决这个优雅的问题(没有模板,因为基础 class )

的确,当用向量调用eval时,两个重载都可以匹配。一种解决方案是将两个重载重命名为不同的名称(例如,evalVecevalMat),并添加一个瘦模板方法调度到正确的方法:

template<typename A, typename B>
void eval(const MatrixBase<A> &a, MatrixBase<B> &b,
          typename enable_if<A::IsVectorAtCompile,void*>::type = 0) {
    this->evalVec(a.derived(),b.derived());
}

template<typename A, typename B>
void eval(const MatrixBase<A> &a, MatrixBase<B> &b,
          typename enable_if<!A::IsVectorAtCompile,void*>::type = 0) {
    this->evalMat(a.derived(),b.derived());
}