Search code examples
c++stdarray

Initialize an std::array of objects with non-trivial constructor


I have a class defined as

class Edgelet
{
private:
    const int e_size;
    //Other private members...
public:
    //The constructor
    explicit Edgelet (int size, Color cl1 = Color::NA, Color cl2 = Color::NA);
    //Other public members...

As there is a const member in the class the default copy constructor is implicitly deleted by the compiler. It needs to be given an argument to initialize.

The problem comes in the class

class Cube
{
private:
    std::array <Edgelet, 12> c_edgelets;
    //Other members...
public:
    //The constructor
    Cube(int size)
    
    //Other public members...

This class contains a std::array of the previous class objects. How do I initialize this array? The size parameter needs to be given to each element of std::array to initialize. I want to set each element of std::array as Edgelet(size - 2).

I could, of course, use initializer list but as there are 12 elements and other parameters to the constructor than shown, the code is getting ugly. Besides I did that with a similar case with 6 elements instead of 12.

I also tried giving default values to parameters but as there is a const member the value can not be changed later on. I also tried looking into std::initializer_list but it seems you cannot add new elements to it (or maybe you can??). Is there an efficient way to do this?


Solution

  • You might write helper class:

    template <std::size_t ... Is, typename T>
    std::array<T, sizeof...(Is)> make_array_impl(const T& def, std::index_sequence<Is...>)
    {
        return {{(Is, void(), def)...}};
    }
    
    template <std::size_t N, typename T>
    std::array<T, N> make_array(const T& def)
    {
        return make_array_impl(def, std::make_index_sequence<N>());
    }
    

    and then

    Cube(int size) : c_edgelets(make_array<12>(Edgelet(size - 2)) {}