How to pass array initialization thru custom structure?

Viewed 116

Usually array could be initialized like this:

int ooo[3][3] =
{
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};

I need to hide it into the custom structure like this:

template <typename T, size_t dim1, size_t dim2>
struct MyStruct
{
private:
    T m_data[dim1][dim2];
};

How to pass the initialization to the array like in the foolowing case?

MyStruct<int, 3, 3> s = 
{
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 }
};
2 Answers

It would work if you can make the member public, and add a set of braces. This is aggregate initialisation:

MyStruct<int, 3, 3> s = 
{{
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 },
}};

I need to hide it into the custom structure ...

If you need the member to be private, you cannot rely on aggregate initialisation since the class won't be an aggregate. You can still achieve similar syntax if you define a custom constructor. Here is an example using std::initializer_list. This one doesn't require the extra braces.

Edit: This isn't as good as the array reference example in the other answer.

MyStruct(std::initializer_list<std::initializer_list<T>> ll)
{
    auto row_in = ll.begin();
    for (auto& row : m_data)
    {
        auto col_in = (row_in++)->begin();
        for (auto& i : row)
        {
            i = *col_in++;
        }
     }
}

You can add a constructor to your class that takes a 2D array argument, and copies it into the array member:

template <typename T, size_t dim1, size_t dim2>
struct MyStruct
{
private:
    T m_data[dim1][dim2];
public:
    MyStruct(T const (&a)[dim1][dim2]) {
        for (int i = 0; i < dim1; ++i)
            for (int j = 0; j < dim2; ++j)
                m_data[i][j] = a[i][j];
    }
};

You also need to add an extra pair of braces at the call site.

Here's a demo.

Related