我在 Eigen 3.4.0 中遇到编译问题。
具体来说,我有一个用于计算三角形面积的模板函数:
template <typename T, int D>
auto TriangleArea(const Eigen::Matrix<T, D, 1>& p0, const Eigen::Matrix<T, D, 1>& p1, const Eigen::Matrix<T, D, 1>& p2) {
const auto e01 = p1 - p0;
const auto e02 = p2 - p0;
return Eigen::sqrt(e01.dot(e01) * e02.dot(e02) - e01.dot(e02) * e01.dot(e02)) / T{2};
}
此代码会导致错误:
没有匹配的调用函数 ‘sqrt(Eigen::ScalarBinaryOpTraits
>::ReturnType)’
如何解决找不到 sqrt 的问题?
模板的问题在于
dot
会产生标量。 Eigen::sqrt
是为 ArrayBase< Derived >
定义的,如here所示。
dot
可以替换为转置乘法,它将返回一个 Eigen
对象。
template <typename T, int D>
auto TriangleArea(const Eigen::Matrix<T, D, 1>& p0, const Eigen::Matrix<T, D, 1>& p1, const Eigen::Matrix<T, D, 1>& p2) {
const auto e01 = p1 - p0;
const auto e02 = p2 - p0;
return Eigen::sqrt(
(e01.transpose() * e01 * e02.transpose() * e02
- e01.transpose() * e02 * e01.transpose() * e02).array()) / T{2};
}
或者,由于在这种情况下
sqrt
的输入是标量,因此可以使用标准 sqrt
。
#include <cmath>
...
template <typename T, int D>
auto TriangleArea(const Eigen::Matrix<T, D, 1>& p0, const Eigen::Matrix<T, D, 1>& p1, const Eigen::Matrix<T, D, 1>& p2) {
const auto e01 = p1 - p0;
const auto e02 = p2 - p0;
return std::sqrt(e01.dot(e01) * e02.dot(e02) - e01.dot(e02) * e01.dot(e02)) / T{ 2 };
}
另一种选择是使用