如何使用initializer_list初始化C++二维数组?编译报错如何解决
问题解答
报错原因
C++标准对二维数组的动态分配语法有明确约束:使用new T[N][M]语法时,仅第一个维度N允许是运行期才能确定的变量,第二个及更高维度M必须是编译期即可确定的常量表达式。
你代码中的column_size是从运行时传入的initializer_list调用size()方法得到的值,哪怕你用const修饰,本质还是运行期变量,不属于编译期常量表达式,因此触发编译错误。
解决方案
方案1:逐行分配二维数组空间
先分配存储行指针的一维数组,再逐行为每一行分配列空间,同时可以直接完成初始化值的拷贝:
#include <initializer_list> using namespace std; class TwoArray{ int** array; size_t row_size; size_t col_size; public: TwoArray(initializer_list<initializer_list<int>> list_){ row_size = list_.size(); col_size = list_.begin()->size(); // 先分配行指针数组 array = new int*[row_size]; size_t row_idx = 0; for (const auto& row : list_) { // 为每一行分配列空间 array[row_idx] = new int[col_size]; size_t col_idx = 0; for (int val : row) { array[row_idx][col_idx++] = val; } row_idx++; } } // 必须配套实现析构函数释放内存,避免泄漏 ~TwoArray() { for (size_t i = 0; i < row_size; i++) { delete[] array[i]; } delete[] array; } // 如需拷贝/移动语义,还需自行实现拷贝构造、拷贝赋值、移动构造、移动赋值函数,避免浅拷贝问题 };
方案2:拍平为一维数组存储(更适合矩阵场景)
矩阵场景更推荐使用连续的一维内存存储二维数据,不仅内存访问性能更高,内存分配释放逻辑也更简单:
#include <initializer_list> using namespace std; class TwoArray{ int* array; size_t row_cnt; size_t col_cnt; public: TwoArray(initializer_list<initializer_list<int>> list_){ row_cnt = list_.size(); col_cnt = list_.begin()->size(); // 一次性分配连续的内存空间 array = new int[row_cnt * col_cnt]{}; size_t pos = 0; for (const auto& row : list_) { for (int val : row) { array[pos++] = val; } } } // 重载访问接口,模拟二维数组访问方式 int& operator()(size_t row, size_t col) { return array[row * col_cnt + col]; } const int& operator()(size_t row, size_t col) const { return array[row * col_cnt + col]; } ~TwoArray() { delete[] array; } };
这个方案不需要逐行释放内存,仅需要释放一次一维数组即可,也不存在行指针额外的内存开销,更适合数学矩阵这类对性能有要求的场景。
内容的提问来源于stack exchange,提问作者Artaza Sameen
相关产品推荐
相关产品推荐

