Eigen 3.4.0:如何实现可接收Map/Matrix并返回同类型Matrix的函数?
优化后的Eigen函数实现
核心思路
借助Eigen的特征类型萃取(traits)自动推导输入的标量类型与矩阵维度,无需手动指定模板参数,同时通过显式实例化解决模板函数必须在头文件定义的问题。
优化代码实现
头文件(foo.h)
#pragma once #include <Eigen/Core> using namespace Eigen; // 利用MatrixBase统一接收Matrix和Map类型,自动推导输出类型 template<typename Derived> typename Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime> foo(const Eigen::MatrixBase<Derived>& data_in) { // 定义与输入同标量、同维度的输出类型 using OutputType = typename Eigen::Matrix<typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime>; OutputType data_out = OutputType::Zero(data_in.rows(), data_in.cols()); // 替换为你的业务逻辑示例 data_out = data_in * 2; return data_out; } // 声明显式实例化(用于将实现移至cpp文件) extern template Matrix<double, Dynamic, Dynamic> foo(const MatrixBase<Matrix<double, Dynamic, Dynamic>>&); extern template Matrix<double, Dynamic, Dynamic> foo(const MatrixBase<Map<Matrix<double, Dynamic, Dynamic>>>&); // 可根据需求添加更多标量类型、维度的实例化声明
实现文件(foo.cpp)
#include "foo.h" // 显式实例化对应类型 template Matrix<double, Dynamic, Dynamic> foo(const MatrixBase<Matrix<double, Dynamic, Dynamic>>&); template Matrix<double, Dynamic, Dynamic> foo(const MatrixBase<Map<Matrix<double, Dynamic, Dynamic>>>&); // 添加其他需要的实例化
关键改进点
- 自动类型推导:通过
MatrixBase<Derived>作为输入参数,利用Derived::Scalar、RowsAtCompileTime、ColsAtCompileTime自动获取输入的标量类型与维度,调用更简洁:// 调用示例 Matrix<double, 3, 3> mat = Matrix<double,3,3>::Ones(); auto res1 = foo(mat); // 自动推导返回Matrix<double,3,3> double arr[9] = {1,2,3,4,5,6,7,8,9}; Map<Matrix<double,3,3>> map_mat(arr); auto res2 = foo(map_mat); // 自动推导返回Matrix<double,3,3> - 消除类型不匹配风险:原实现手动指定
T易出现类型错误,优化后通过Eigen的traits保证输入输出类型一致。 - 支持分离编译:显式实例化允许将模板函数实现移至cpp文件,减少头文件编译开销,避免不良的头文件全量模板定义。
- 兼容性:完全适配Eigen 3.4.0,
MatrixBase是所有Eigen矩阵类(含Matrix和Map)的基类,可正确接收两种类型输入。
内容的提问来源于stack exchange,提问作者kt-kbr
相关产品推荐
相关产品推荐

