Search code examples
eigen

different behaviors between Eigen::Ref and Eigen::MatrixBase


I am wondering why the following code generates a compile-time error:

void f(const double e) {}

void f(const Eigen::Ref<const MatrixX<double>>& g) {}

int main {
  Eigen::Matrix<double, 2, 1> m1;
  Eigen::Matrix<double, 2, 1> m2;
  m1 << 1.0, 2.0;
  m2 << 1.0, 2.0;
  f(m1.transpose() * m2);  // error: call to 'f' is ambiguous
}

while the following one doesn't.

void f(const double e) {}

template <typename Derived>
void f(const Eigen::MatrixBase<Derived>& m) {}

int main {
  Eigen::Matrix<double, 2, 1> m1;
  Eigen::Matrix<double, 2, 1> m2;
  m1 << 1.0, 2.0;
  m2 << 1.0, 2.0;
  f(m1.transpose() * m2);  // no error
}

Solution

  • This because in your case m1.transpose() * m2 is an inner product that is allowed to be assigned to a scalar:

    double v = m1.transpose() * m2;
    

    This is the unique situation where a 1x1 matrix expression is allowed to be converted to a scalar. In the second version there is no ambiguity because the type of the expression m1.transpose() * m2 inherits MatrixBase.