C++三维动态数组创建与显示报错(E0142)求助
三维矩阵元素访问E0142错误的解决方案
问题根源
当前Array3D类的operator[]直接返回T*,导致三级下标访问m_data3D[i][j][k]逻辑不成立:
m_data3D[i]返回的是指向第i行起始位置的float*m_data3D[i][j]取到的是该指针偏移j后的float值- 对基础类型
float使用[k]下标访问属于非法操作,触发E0142编译错误
修复方案
给Array3D添加一个代理类,通过两次重载operator[]实现三级下标访问:
修改后的Array3D.h代码
#pragma once #ifndef _ARRAY_3D_H_ #define _ARRAY_3D_H_ #include <cassert> #include <vector> using namespace std; template<typename T> class Array3D { // 代理类:处理二级下标访问 class RowProxy { public: RowProxy(T* data, size_t depth) : m_data(data), m_depth(depth) {} // 二级下标访问,返回指向深度维度的指针 T* operator[](size_t c) { assert(c >= 0 && c < m_depth); return m_data + c * m_depth; } const T* operator[](size_t c) const { assert(c >= 0 && c < m_depth); return m_data + c * m_depth; } private: T* m_data; size_t m_depth; }; public: typedef Array3D<T> _Myt; Array3D() : m_nRows(0) , m_nCols(0) , m_nDepths(0) {} Array3D(size_t r, size_t c, size_t d) { Resize(r, c, d); } void Resize(size_t r, size_t c, size_t d) { if (r == m_nRows && c == m_nCols && d == m_nDepths) { return; } bool bValid = r > 0 && c > 0 && d > 0; if (!bValid) return; m_nRows = r; m_nCols = c; m_nDepths = d; m_v.resize(m_nRows * m_nCols * m_nDepths); } // 一级下标访问,返回代理对象 RowProxy operator[](size_t r) { assert(r >= 0 && r < m_nRows); return RowProxy(&m_v[r * m_nCols * m_nDepths], m_nDepths); } const RowProxy operator[](size_t r) const { assert(r >= 0 && r < m_nRows); return RowProxy(const_cast<T*>(&m_v[r * m_nCols * m_nDepths]), m_nDepths); } const T* GetRawPointer() const { return &(m_v[0]); } T* GetRawPointer() { return &(m_v[0]); } long Rows() const { return static_cast<long>(m_nRows); } long Cols() const { return static_cast<long>(m_nCols); } long Depths() const { return static_cast<long>(m_nDepths); } long TotalSize() const { return static_cast<long>(m_nRows * m_nCols * m_nDepths); } void ClearUp() { m_nRows = 0; m_nCols = 0; m_nDepths = 0; m_v.clear(); } bool IsEmpty() const { return m_v.empty(); } protected: vector<T> m_v; size_t m_nRows; size_t m_nCols; size_t m_nDepths; };
说明
修改后,m_data3D[i][j][k]的访问逻辑变为:
m_data3D[i]返回RowProxy对象,指向第i行的起始数据m_data3D[i][j]通过代理类的operator[]返回指向第i行第j列起始位置的float*m_data3D[i][j][k]访问该指针的第k个元素,符合三维数组的访问逻辑
原Matrix3D::display函数无需修改,即可正常编译运行。
内容的提问来源于stack exchange,提问作者Master Zhang
相关产品推荐
相关产品推荐

