user3600124
user3600124

Reputation: 883

how to initialize 2D array from initializer_list

typedef unsigned char u8;

template <u8 N>
class matrix {
    public:
        matrix(const std::initializer_list<std::initializer_list<int>>& l);
    private:
        std::array<std::array<int, N>, N> arr;
};

template <u8 N>
matrix<N>::matrix(const std::initializer_list<std::initializer_list<int>>& l) : arr(l) {}

error C2664: 'std::array,2>::array(std::array,2> &&)': cannot convert argument 1 from 'const std::initializer_list>' to 'const std::array,2> &'

How do I initialize 2D std::array (or C array for that matter) from 2D std::initializer_list?

Upvotes: 2

Views: 2311

Answers (1)

NathanOliver
NathanOliver

Reputation: 180955

std::array is an aggregate. That means you can initialize it from a braced-init-list like

std::array<int, 4> foo = {1,2,3,4};

In your constructor though you don't braced-init-list, you have a std::initlizer_list, which cannot be used to initialize a std::array. What you would have to do is copy the data from the std::initlizer_list into the array like

template <u8 N>
matrix<N>::matrix(std::initializer_list<std::initializer_list<int>> l)
{
    u8 counter = 0;
    for (auto row : l)
        std::copy(row.begin(), row.end(), arr[counter++].begin());
}

Also note that you don't have to pass the by std::initlizer_list reference. It is a lightweight object and passing by value is fine, it wont copy the underlying elements.


You could change you class to take a the 2d array as a parameter so you can directly initialize arr with that but because of how you have to initialize aggregates of aggregates you get into curly brace hell as your code would become

typedef unsigned char u8;

template <u8 N>
class matrix {
    public:
        matrix(std::array<std::array<int, N>, N> l);
    private:
        std::array<std::array<int, N>, N> arr;
};

template <u8 N>
matrix<N>::matrix(std::array<std::array<int, N>, N> l) : arr(l) {}


int main()
{
    std::array<std::array<int, 2>, 2> arr{{{{1, 2}}, {{3, 4}}}}; // this is how you have to initialize a 2d std::array

    matrix<2> m = {{{{{1, 2}}, {{3, 4}}}}}; // we need one more brace here since we are initialzing the matrix, which needs its own brace
}

Upvotes: 1

Related Questions