【问题标题】:How to initialize a two dimensional array using initializer_lists?如何使用 initializer_lists 初始化二维数组?
【发布时间】:2021-09-04 10:08:14
【问题描述】:

我已经编写了这个构造函数来使用initializer_lists初始化我的二维数组。

using namespace std;

class TwoArray{
    int** array;

public:
    TwoArray(initializer_list<initializer_list<int>> list_){
        const size_t row_size = list_.size();
        const size_t column_size = list_.begin()->size();
        
        array = new int[row_size][column_size]{};
    }
};

但是,这段代码显示了这个错误:

main.cpp: In constructor ‘TwoArray::TwoArray(std::initializer_list<std::initializer_list<int> >)’:
main.cpp:19:48: error: array size in new-expression must be constant
         array = new int[row_size][column_size]{};
                                                ^
main.cpp:19:48: error: the value of ‘column_size’ is not usable in a constant expression
main.cpp:13:22: note: ‘column_size’ was not initialized with a constant expression
         const size_t column_size = list_.begin()->size();

是的,我知道每列的长度可能不同,但为了简单起见,我删除了一些代码。实际上,我正在为 C++ 编写一个数学矩阵数据结构。而且我也知道二维数组可以看成一维的,用一维initializer_list可以很方便的初始化。

如何绕过此错误?为什么会出现这个错误?

【问题讨论】:

  • 你认为new T[n][m]在做什么?
  • evg ,我认为new T[n][m]正在分配一个新的二维顺序数组n*m
  • 构造函数TwoArray(initializer_list&lt;initializer_list&lt;int&gt;&gt; list_)private

标签: c++ arrays initializer-list


【解决方案1】:

你需要先创建一个指针数组,然后用 int 数组初始化它们。请注意,如果任何分配引发异常,这可能会泄漏。

array = new int*[row_size];
for(std::size_t i = 0; i < row_size; ++i)
    array[i] = new int[column_size]{};

然后类似地delete每个子数组。

for(std::size_t i = 0; i < row_size; ++i)
    delete[] array[i];
delete[] array;

不过,除非您从直接拥有内存中受益,否则请考虑改用std::vector&lt;std::vector&lt;int&gt;&gt;(或std::unique_ptr&lt;std::unique_ptr&lt;int[]&gt;[]&gt;)。

【讨论】:

  • 或者更好,线性std::vector&lt;int&gt; 和一些索引算法。
【解决方案2】:

如果您的行长度是编译时间常数,C++11 允许

auto array = new int [row_size][CONSTANT];

否则,您可以使用指向数组的指针数组来允许 2D 语法,例如连续的 2D 数组,即使它不是一个有效的单一大分配。您可以使用循环对其进行初始化,如下所示:

TwoArray(initializer_list<initializer_list<int>> list_){
        const size_t row_size = list_.size();
        const size_t column_size = list_.begin()->size();
        
        array = new int*[row_size];
        for(int i = 0; i < row_size; ++i)
            array[i] = new int[column_size];
    }

【讨论】:

    【解决方案3】:

    我做了这个例子,所以你可以输入:

    array<int, 2, 3> my_array{ {{0,1}, {2,3}, {4,5}} };
    

    尚未完全测试,但可以帮助您入门。 它还展示了如何在不需要“新建”或“删除”的情况下实现它。

    #include <cassert>
    #include <array>
    
    template<typename type_t, size_t COLS, size_t ROWS>
    struct array
    {
        array(const type_t(&values)[ROWS][COLS])
        {
            for (auto c = 0; c < COLS; ++c)
            {
                for (auto r = 0; r < ROWS; ++r)
                {
                    at(c, r) = values[r][c];
                }
            }
        }
    
        type_t& at(const std::size_t column, const std::size_t row)
        {
            assert(row < m_rows);           // row out of range
            assert(column < m_columns);     // column out of range
    
            auto index = (row * COLS) + column;
            return m_data[index];
        }
    
        type_t& operator()(const std::size_t column, const std::size_t row)
        {
            return at(column, row);
        }
    
    private:
        const type_t m_rows{ ROWS };
        const type_t m_columns{ COLS };
        std::array<type_t, ROWS* COLS> m_data{};
    };
    
    int main()
    {
        array<int, 2, 3> arr{ {{0,1}, {2,3}, {4,5}} };
    
        assert(arr(1, 1) == 3);
        assert(arr(1, 2) == 5);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-12-08
      • 1970-01-01
      • 2012-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多