如何从嵌套的 std::initializer_list 初始化 2D C 样式数组?

问题描述 投票:0回答:2

我正在创建一个

Matrix<type, width, height>
类,我希望能够使用
initializer_list
进行初始化,例如:

Matrix<int, 2, 2> mat = Matrix<int, 2, 2>{ {1,2},{3,4} };

矩阵是使用

T[height][width]
2D 数组实现的。

为此,我尝试制作一个构造函数,例如:

Matrix(std::initializer_list< std::initializer_list<T>> input);

但是,我不知道如何从列表中填充数组。我试过了

  • 使用

    memcpy
    (损坏的内存),

  • std::copy
    (似乎无法从
    std::initializer_list
    ),

  • 以及使用 赋值运算符
    ()
    构造函数调用 (但是二维数组是不可赋值的,并且 () 构造函数调用也不能 编译)。

有没有其他方法,最好是尽可能安全的方法来做到这一点?

c++ c++11 templates multidimensional-array stdinitializerlist
2个回答
4
投票

您应该向

Matrix(std::initializer_list</* here */> list);
提供准确的类型。 然后要填充数组,您需要迭代传递的列表并填充数组。 (在线观看直播)

#include <initializer_list> // std::initializer_list

template<typename T, std::size_t R, std::size_t C>
class Matrix
{
    T mArray2D[R][C]{};

public:
    Matrix(const std::initializer_list<T[C]> list)
    //                                 ^^^^^ --> type of the row
    {
        auto iter{ list.begin() }; // returns pointer to T[C]
        for (std::size_t row{}; row < R; ++row)
        {
            const auto& rowElements{ *iter };
            for (std::size_t col{}; col < C; ++col)
            {
                mArray2D[row][col] = rowElements[col];
            }
            ++iter;
        }
    }
};

现在在

main()
中,您可以使用初始化列表来初始化
Matrix
,如下所示:

Matrix<int, 2, 2> mat{ {1,2}, {3,4} };
// or
// Matrix<int, 2, 2> mat = { {1,2}, {3,4} };

如果您可以使用

std::array
,您可以执行以下操作。 (在线观看直播)

#include <iostream>
#include <array>            // std::array
#include <initializer_list> // std::initializer_list

template<typename T, std::size_t R, std::size_t C>
class Matrix
{
    using RowType = std::array<T, C>;
    T mArray2D[R][C]{};

public:
    Matrix(const std::initializer_list<RowType> list)
    {
        auto iter{ list.begin() };
        for (std::size_t row{}; row < R; ++row)
        {
            const RowType& rowElements{ *iter };
            for (std::size_t col{}; col < C; ++col)
            {
                mArray2D[row][col] = rowElements[col];
            }
            ++iter;
        }
    }
};

如果类中的多维数组可以是类型为 std::array

std::array
T
,您也可以使用
std::copy
(在线观看直播)

#include <iostream>
#include <array>            // std::array
#include <initializer_list> // std::initializer_list
#include <algorithm>        // std::copy

template<typename T, std::size_t R, std::size_t C>
class Matrix
{
    using RowType = std::array<T, C>;
    using Array2D = std::array<RowType, R>;
    Array2D mArray{ RowType{} }; // initialize the matrix

public:
    Matrix(const std::initializer_list<RowType> list)
    {
       std::copy(list.begin(), list.end(), mArray.begin());
    }
};

0
投票

在初始化列表中不使用 std::array 的另一个示例

#include <iostream>
#include <array>            // std::array
#include <initializer_list> // std::initializer_list
#include <algorithm>        // std::copy

template<typename T>
concept scalar = std::arithmetic<T> || std::floating_point<T>;

namespace mat
{
template<scalar T, size_t COLS, size_t ROWS>
struct type : std::array<vec::type<T, ROWS>, COLS>
{
   type(std::initializer_list<T[ROWS]> src)
   {
       auto iter = src.begin();
       for(size_t cols = 0; (cols < COLS) && (iter != src.end()); ++cols)
          (*this)[cols] = *reinterpret_cast<const vec::type<T, ROWS>*>(iter++);
   }
};
};
© www.soinside.com 2019 - 2024. All rights reserved.