如何扩展Eigen的Tensor类以添加自定义成员方法?
首先,Eigen的Tensor类没有提供官方的扩展点直接新增成员函数,直接修改Eigen源码虽然能实现需求,但会导致后续版本升级困难,优先推荐低侵入的实现方案:
方案1:C++23 扩展方法实现(最推荐,无需修改Eigen源码)
如果你的编译器支持C++23,可以用**推导this(Deducing this)**特性直接给Eigen::Tensor类加扩展方法,完全不需要动Eigen的任何代码:
#include <Eigen/CXX11/Tensor> #include <iostream> template<typename Derived> requires std::is_base_of_v<Eigen::TensorBase<Derived>, Derived> void shape(this const Derived& x) { std::cout << "( "; for (int i = 0; i < x.NumDimensions; i++){ std::cout << x.dimensions()[i]; // 去掉最后一维多余的逗号 if (i != x.NumDimensions - 1) std::cout << ","; } std::cout << " )" << std::endl; }
调用方式和你预期的几乎一致:
Eigen::Tensor<double,2> t(2,2); t.shape(); // 输出 ( 2,2 )
方案2:兼容低版本C++的包装类实现
如果需要兼容C++11/14/17,可以自定义Tensor包装类继承原生Eigen::Tensor,在包装类中添加shape方法:
#include <Eigen/CXX11/Tensor> #include <iostream> template<typename Scalar_, int rank> class CustomTensor : public Eigen::Tensor<Scalar_, rank> { public: // 继承Eigen::Tensor的所有构造函数 using Eigen::Tensor<Scalar_, rank>::Tensor; void shape() const { std::cout << "( "; for (int i = 0; i < this->NumDimensions; i++){ std::cout << this->dimensions()[i]; if (i != this->NumDimensions - 1) std::cout << ","; } std::cout << " )" << std::endl; } };
调用方式:
CustomTensor<double,2> t(2,2); t.shape(); // 输出 ( 2,2 )
这个方案可以保留Eigen::Tensor的所有原有功能,只需要把原来的Eigen::Tensor替换为CustomTensor声明变量即可。
方案3:直接修改Eigen源码(不推荐)
如果一定要在原生Eigen::Tensor上调用该方法,可以手动修改Eigen的源码文件:找到Eigen安装目录下的unsupported/Eigen/CXX11/src/Tensor/Tensor.h,在Tensor类的public成员区域添加如下代码:
void shape() const { std::cout << "( "; for (int i = 0; i < NumDimensions; i++){ std::cout << dimensions()[i]; if (i != NumDimensions - 1) std::cout << ","; } std::cout << " )" << std::endl; }
该方案的缺点是后续升级Eigen版本时需要重新修改对应文件,容易出现兼容问题,非特殊情况不建议使用。
补充:你原始实现的shape函数会在最后一维后面多输出一个逗号,比如二维张量会输出
( 2,2, ),上面的代码已经修复了这个问题。
内容的提问来源于stack exchange,提问作者Nicolas Brugie
相关产品推荐
相关产品推荐

