Eigen类型重载构造函数调用歧义问题求解
解决Eigen构造函数调用歧义问题
问题原因
m.transpose()返回的是**Eigen::Transpose<Eigen::Matrix<double, 3, 3>>**类型的表达式对象,而非直接的Eigen::Matrix3d。Eigen的模板构造机制允许将这类表达式隐式转换为任意稠密矩阵/向量类型,尽管维度不匹配的转换在运行时会报错,但编译阶段编译器认为转换到Matrix3d和Vector4d的路径代价相同,因此产生调用歧义。
解决方法
方法1:显式转换为目标类型
直接将表达式显式转换为Matrix3d,明确指定要调用的构造函数:
#include <Eigen/Core> class MyClass { public: MyClass(const Eigen::Matrix3d& m) {} MyClass(const Eigen::Vector4d& v) {} }; int main(int argc, char** argv) { Eigen::Matrix3d m; // 显式转换为Matrix3d消除歧义 MyClass t1(static_cast<Eigen::Matrix3d>(m.transpose())); }
方法2:用SFINAE限制构造函数适用范围
通过模板和std::enable_if,让每个构造函数仅接受能转换为对应目标类型的Eigen表达式,从根源避免歧义:
#include <Eigen/Core> #include <type_traits> class MyClass { public: // 仅匹配可转换为Matrix3d的Eigen表达式 template<typename Derived, typename = std::enable_if_t<std::is_convertible_v<const Eigen::MatrixBase<Derived>&, Eigen::Matrix3d>>> MyClass(const Eigen::MatrixBase<Derived>& m) { Eigen::Matrix3d mat = m; // 按需转换为具体矩阵类型 } // 仅匹配可转换为Vector4d的Eigen表达式 template<typename Derived, typename = std::enable_if_t<std::is_convertible_v<const Eigen::MatrixBase<Derived>&, Eigen::Vector4d>>> MyClass(const Eigen::MatrixBase<Derived>& v) { Eigen::Vector4d vec = v; // 按需转换为具体向量类型 } }; int main(int argc, char** argv) { Eigen::Matrix3d m; MyClass t1(m.transpose()); // 无歧义,自动匹配Matrix3d对应的模板构造函数 }
方法3:将Vector4d构造函数设为explicit
如果不需要隐式接受Vector4d类型的转换,可将其构造函数标记为explicit,编译器将不再考虑隐式转换到Vector4d的路径:
#include <Eigen/Core> class MyClass { public: MyClass(const Eigen::Matrix3d& m) {} // 标记为explicit,禁止隐式转换 explicit MyClass(const Eigen::Vector4d& v) {} }; int main(int argc, char** argv) { Eigen::Matrix3d m; MyClass t1(m.transpose()); // 无歧义,仅匹配Matrix3d构造函数 // 使用Vector4d构造需显式传入 Eigen::Vector4d v; MyClass t2(v); // 正常编译 }
内容的提问来源于stack exchange,提问作者jlack
相关产品推荐
相关产品推荐

