在调用针对不同特征矩阵类型重载的函数时避免使用 eval

问题描述

我经常发现自己为不同的特征矩阵类型重载了函数。 根据我如何称呼它们,需要在参数上显式调用 eval() 以提示正确的重载,例如当所有都是惰性求值时 CwiseBinaryOps:

#include <Eigen/Dense>
void ef(Eigen::Vector2d const& v) {}
void ef(Eigen::Vector3d const& v) {}
int main() {
    ef(Eigen::Vector3d() + Eigen::Vector3d()); // ambiguous call to overloaded function
    ef((Eigen::Vector3d() + Eigen::Vector3d()).eval());
}

这是一个 godbolt

有没有办法避免这种情况?

解决方法

Eigen::Vector3d() + Eigen::Vector3d() 的类型是表达式模板。在调用 Eigen::Vector3d 之前,它不会计算为 eval()

如果不想显式调用eval()ef函数需要将表达式模板作为参数,例如

#include <Eigen/Dense>

template <typename Derived>
void ef(Eigen::MatrixBase<Derived> const& v) {}

int main()
{
    ef(Eigen::Vector2d() + Eigen::Vector2d());
    ef(Eigen::Vector3d() + Eigen::Vector3d());
}

您可以检查 ef 中 v 的大小,以便为 Vector2dVector3d 做不同的事情。