不同类型的特征矩阵之间算术后的模糊重载
Ambiguous overload after arithmetic between different types of Eigen matrices
我在针对不同类型的特征矩阵(准确地说是列和矩阵)的函数重载中遇到了问题。当输入是一些简单算术的结果时,重载失败。特别是:
#include <Eigen/Eigen>
#include <iostream>
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatD;
typedef Eigen::Matrix<double, Eigen::Dynamic, 1, Eigen::ColMajor> ColD;
ColD multiply(const ColD &A){ return 2. * A; }
MatD multiply(const MatD &A){ return 2. * A; }
int main()
{
ColD A = ColD::Ones(10);
MatD B = MatD::Ones(10,10);
// overload is correct
std::cout << multiply(A) << std::endl;
std::cout << multiply(B) << std::endl;
// compiler error: "error: call to 'multiply' is ambiguous"
std::cout << multiply(A+A) << std::endl;
std::cout << multiply(B+B) << std::endl;
return 0;
}
即基于 A
和 B
的重载被正确编译。但是当我执行 A+A
和 B+B
时,编译器无法识别正确的重载。 我可以通过做两行来解决这个问题,可能会使用一些临时变量,但我不想这样做。我怎样才能让这个重载为此工作'one-liner' ?
我认为这是 Eigen 的特殊性,但到目前为止我无法准确理解是哪种特殊性以及如何避免它。
如评论中所述,Eigen 的运算符不生成普通矩阵或向量,而是生成运算对象(例如 Eigen::CwiseBinaryOp<...>
)。
您可以像这样将运算转换为普通矩阵...
std::cout << multiply(ColD(A + A)) << std::endl;
std::cout << multiply(MatD(B + B)) << std::endl;
... 或使 multiply
成为接受各种格式的模板。语法变得有点难看,但是:
template <typename Derived>
Eigen::Matrix<
typename Eigen::internal::traits<Derived>::Scalar,
Eigen::internal::traits<Derived>::RowsAtCompileTime,
Eigen::internal::traits<Derived>::ColsAtCompileTime>
multiply(const Derived& A)
{
return 2.0 * A;
}
模板参数为Derived
,可以是矩阵,向量,Eigen的任意操作对象。 return 值是一个 Eigen::Matrix
,我们通过 traits
模板从 Derived
中提取其特征。
我在针对不同类型的特征矩阵(准确地说是列和矩阵)的函数重载中遇到了问题。当输入是一些简单算术的结果时,重载失败。特别是:
#include <Eigen/Eigen>
#include <iostream>
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatD;
typedef Eigen::Matrix<double, Eigen::Dynamic, 1, Eigen::ColMajor> ColD;
ColD multiply(const ColD &A){ return 2. * A; }
MatD multiply(const MatD &A){ return 2. * A; }
int main()
{
ColD A = ColD::Ones(10);
MatD B = MatD::Ones(10,10);
// overload is correct
std::cout << multiply(A) << std::endl;
std::cout << multiply(B) << std::endl;
// compiler error: "error: call to 'multiply' is ambiguous"
std::cout << multiply(A+A) << std::endl;
std::cout << multiply(B+B) << std::endl;
return 0;
}
即基于 A
和 B
的重载被正确编译。但是当我执行 A+A
和 B+B
时,编译器无法识别正确的重载。 我可以通过做两行来解决这个问题,可能会使用一些临时变量,但我不想这样做。我怎样才能让这个重载为此工作'one-liner' ?
我认为这是 Eigen 的特殊性,但到目前为止我无法准确理解是哪种特殊性以及如何避免它。
如评论中所述,Eigen 的运算符不生成普通矩阵或向量,而是生成运算对象(例如 Eigen::CwiseBinaryOp<...>
)。
您可以像这样将运算转换为普通矩阵...
std::cout << multiply(ColD(A + A)) << std::endl;
std::cout << multiply(MatD(B + B)) << std::endl;
... 或使 multiply
成为接受各种格式的模板。语法变得有点难看,但是:
template <typename Derived>
Eigen::Matrix<
typename Eigen::internal::traits<Derived>::Scalar,
Eigen::internal::traits<Derived>::RowsAtCompileTime,
Eigen::internal::traits<Derived>::ColsAtCompileTime>
multiply(const Derived& A)
{
return 2.0 * A;
}
模板参数为Derived
,可以是矩阵,向量,Eigen的任意操作对象。 return 值是一个 Eigen::Matrix
,我们通过 traits
模板从 Derived
中提取其特征。