如何从std::vector<std::array<double,16>>中无冗余提取3x3矩阵参与运算
需求实现方案
首先可以明确:你的需求完全可以实现,只需要做两层无数据冗余的轻量视图封装即可,不需要复制原矩阵数据,完全兼容你已经实现的std::array<double, 9>运算逻辑。
实现思路
核心是通过两个只持有原数据引用的视图类完成需求:
- 单矩阵视图:持有单个4x4矩阵的引用,负责提取指定位置的元素适配3x3矩阵的运算接口
- 容器视图:持有原vector的引用,重载下标运算符返回单矩阵视图,实现
someStructure[i]的访问格式
代码示例
第一步:定义索引映射和单矩阵视图
#include <vector> #include <array> // 4x4矩阵到3x3矩阵的索引映射 constexpr std::array<int, 9> MAT4_TO_MAT3_IDX = {0, 1, 2, 4, 5, 6, 8, 9, 10}; // 单个4x4矩阵到3x3矩阵的视图 class Mat3View { private: const std::array<double, 16>& source_mat; public: explicit Mat3View(const std::array<double, 16>& mat) : source_mat(mat) {} // 隐式转换为std::array<double, 9>,直接适配你已实现的所有3x3矩阵运算 operator std::array<double, 9>() const { std::array<double, 9> res; for (int i = 0; i < 9; ++i) { res[i] = source_mat[MAT4_TO_MAT3_IDX[i]]; } return res; } // 可选:直接重载加法,省去隐式转换的临时对象开销 friend std::array<double, 9> operator+(const Mat3View& a, const Mat3View& b) { std::array<double, 9> res; for (int i = 0; i < 9; ++i) { res[i] = a.source_mat[MAT4_TO_MAT3_IDX[i]] + b.source_mat[MAT4_TO_MAT3_IDX[i]]; } return res; } };
第二步:定义容器视图
class Mat3ViewContainer { private: const std::vector<std::array<double, 16>>& source_vec; public: explicit Mat3ViewContainer(const std::vector<std::array<double, 16>>& vec) : source_vec(vec) {} // 重载下标运算符,返回单矩阵视图 Mat3View operator[](size_t index) const { return Mat3View(source_vec[index]); } // 可选:实现size方法兼容std容器接口 size_t size() const { return source_vec.size(); } };
第三步:使用示例
// 你的原数据 std::vector<std::array<double, 16>> original_matrices = /* 你的原始数据 */; // 构造视图,无任何数据复制,完全无冗余 Mat3ViewContainer someStructure(original_matrices); // 你要求的运算格式可以直接执行 std::array<double, 9> tst = someStructure[0] + someStructure[1];
注意事项
- 所有视图类仅持有原数据的引用,需要保证原数据的生命周期长于视图对象,避免出现悬空引用
- 如果需要修改原数据中3x3矩阵对应位置的元素,只需要给
Mat3View添加非const引用版本和赋值运算符重载即可 - 如果需要适配更多你已经实现的3x3矩阵运算,只需要给
Mat3View添加对应的运算符重载即可,不需要修改原有运算逻辑
内容的提问来源于stack exchange,提问作者user8458838
相关产品推荐
相关产品推荐

