如何在运行时区分Eigen Array与Eigen Matrix?
在单个Eigen模板函数中区分Matrix和Array
你可以借助C++的类型特征结合Eigen的类层次结构,在单个模板函数内实现对Matrix和Array的区分,同时避免代码冗余。以下是两种可行方案:
方案1:使用C++17 if constexpr(推荐)
利用编译期分支判断,直接在函数内区分类型,编译时会剔除无用分支,兼顾简洁与效率:
#include <Eigen/Core> #include <type_traits> #include <iostream> template<typename Derived> void foo(Eigen::EigenBase<Derived>& base) { if constexpr (std::is_base_of_v<Eigen::MatrixBase<Derived>, Derived>) { // 执行Matrix专属操作 std::cout << "处理Matrix类型" << std::endl; auto& mat = static_cast<Eigen::MatrixBase<Derived>&>(base); // 示例:调用Matrix的transpose方法 auto transposed = mat.transpose(); } else if constexpr (std::is_base_of_v<Eigen::ArrayBase<Derived>, Derived>) { // 执行Array专属操作 std::cout << "处理Array类型" << std::endl; auto& arr = static_cast<Eigen::ArrayBase<Derived>&>(base); // 示例:调用Array的abs方法 auto abs_arr = arr.abs(); } else { // 处理其他Eigen表达式类型(如临时计算结果) std::cout << "处理其他Eigen类型" << std::endl; } }
方案2:标签分发(兼容C++11/14)
如果你的环境不支持C++17,可以用标签分发技术,通过内部实现函数区分类型,对外保持单一入口:
#include <Eigen/Core> #include <type_traits> #include <iostream> namespace detail { // Matrix类型的实现 template<typename Derived> void foo_impl(Eigen::MatrixBase<Derived>& mat) { std::cout << "处理Matrix类型" << std::endl; auto transposed = mat.transpose(); } // Array类型的实现 template<typename Derived> void foo_impl(Eigen::ArrayBase<Derived>& arr) { std::cout << "处理Array类型" << std::endl; auto abs_arr = arr.abs(); } } template<typename Derived> void foo(Eigen::EigenBase<Derived>& base) { using IsMatrix = std::is_base_of<Eigen::MatrixBase<Derived>, Derived>; if (IsMatrix::value) { detail::foo_impl(static_cast<Eigen::MatrixBase<Derived>&>(base)); } else { detail::foo_impl(static_cast<Eigen::ArrayBase<Derived>&>(base)); } }
说明
- 两种方案都无需编写多个重载函数,通过编译期类型判断实现分支逻辑,避免代码冗余。
- Eigen中大部分临时表达式(如
mat + arr的结果)继承自EigenBase但不属于Matrix/Array,可通过else分支处理这类场景。
内容的提问来源于stack exchange,提问作者GregReese
相关产品推荐
相关产品推荐

