基于线性存储实现C++二维数组的函数及简化方法问询
更简便的线性存储二维数组操作方案
当然有更简洁、更贴合C++风格的方式来实现这类线性存储的二维数组操作,下面是几个实用的方案:
1. 模板函数自动推导类型
原来的two_d_store需要手动传递元素字节大小,用模板函数可以让编译器自动推导类型,省去这个参数,代码更简洁安全:
template <typename T> void two_d_store(T* base, size_t total_rows, size_t total_cols, size_t row_idx, size_t col_idx, T value) { // 行优先计算偏移(和原生二维数组存储逻辑一致) size_t offset = row_idx * total_cols + col_idx; *(base + offset) = value; } // 调用示例 char d[10*20*sizeof(int)]; two_d_store(reinterpret_cast<int*>(d), 10, 20, 4, 0, 576);
如果你的线性缓冲区本来就是对应类型的指针(比如直接用int d[200];),连reinterpret_cast都可以省,直接调用two_d_store(d, 10, 20, 4, 0, 576);就行。
2. 封装成二维数组类,模拟原生数组语法
如果想让操作和原生二维数组完全一致,可以封装一个轻量级的类,重载[]运算符,让代码可读性拉满:
template <typename T> class Linear2DArray { private: T* m_data; size_t m_cols; size_t m_rows; // 可选:添加行数用于边界检查 public: Linear2DArray(T* data_ptr, size_t rows, size_t cols) : m_data(data_ptr), m_rows(rows), m_cols(cols) {} // 返回对应行的指针,支持arr[i][j]的写法 T* operator[](size_t row_idx) { // 可选:添加边界检查,避免越界 if (row_idx >= m_rows) throw std::out_of_range("Row index out of bounds"); return m_data + row_idx * m_cols; } // 常量版本,用于只读访问 const T* operator[](size_t row_idx) const { if (row_idx >= m_rows) throw std::out_of_range("Row index out of bounds"); return m_data + row_idx * m_cols; } }; // 调用示例 char buffer[10*20*sizeof(int)]; int* d = reinterpret_cast<int*>(buffer); Linear2DArray<int> arr(d, 10, 20); arr[4][0] = 576; // 和原生int d[10][20]; d[4][0] = 576; 写法完全一致
这个方案还可以扩展添加更多安全校验,比如列索引的边界检查,进一步提升代码健壮性。
3. 用C++20的std::span实现现代风格的二维视图
如果你使用C++20及以上版本,std::span可以轻松创建二维的视图,不用自己写类:
#include <span> #include <vector> // 创建二维span视图 template <typename T> std::vector<std::span<T>> make_2d_span(T* data, size_t rows, size_t cols) { std::vector<std::span<T>> result; result.reserve(rows); for (size_t i = 0; i < rows; ++i) { result.emplace_back(data + i * cols, cols); } return result; } // 调用示例 char buffer[10*20*sizeof(int)]; int* d = reinterpret_cast<int*>(buffer); auto arr = make_2d_span(d, 10, 20); arr[4][0] = 576; // 同样支持原生数组的写法
std::span是标准库提供的轻量级视图,不会拷贝数据,只是对原有线性存储的包装,非常高效,还能和其他标准库组件无缝配合。
注意事项
以上方案默认都是行优先存储(和C++原生二维数组的存储逻辑一致),如果需要列优先存储,只需要把偏移计算改成offset = col_idx * total_rows + row_idx即可。
内容的提问来源于stack exchange,提问作者zachem64
相关产品推荐
相关产品推荐

