I am creating a Matrix<type, width, height>
class which I want to be able to initialize using initializer_list
, for instance:
Matrix<int, 2, 2> mat = Matrix<int, 2, 2>{ {1,2},{3,4} };
The matrix is implemented using a T[height][width]
2D array.
To do this, I have tried making a constructor such as:
Matrix(std::initializer_list< std::initializer_list<T>> input);
However, I do not know how to fill the array with from the list. I have tried
using memcpy
(corrupted memory),
std::copy
(seems it is not possible to copy from an
std::initializer_list
),
()
constructor call
(but 2D arrays are not assignable and () constructor call does not
compile).Is there any other way, preferably as safe as possible, to do this?
You should provide exact type to the Matrix(std::initializer_list</* here */> list);
.
Then to fill the array, you need to iterate through the list passed and fill the array. (See live online)
#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;
}
}
};
Now in the main()
you can initialize Matrix
using an initializer list as follows:
Matrix<int, 2, 2> mat{ {1,2}, {3,4} };
// or
// Matrix<int, 2, 2> mat = { {1,2}, {3,4} };
If you could use std::array
, you could do the following. (See live online)
#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;
}
}
};
If the multidimensional array in the class could be an std::array
of std::array
of type T
, you could use std::copy
as well. (See live online)
#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());
}
};