Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

stdarray

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?

like image 327
Jatin Avatar asked Apr 10 '26 14:04

Jatin


2 Answers

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)) {}
like image 109
Jarod42 Avatar answered Apr 16 '26 15:04

Jarod42


If array members are not default constructible, you have to provide an initiailzer for each element. Instead of doing that, you can use a std::vector instead of a std::array. std::vector has a constructor with the form of

constexpr vector( size_type count,
                  const T& value,
                  const Allocator& alloc = Allocator());
                  

that will construct count objects initialized with value. That would make your code look like

class Cube
{
private:
    std::vector<Edgelet> c_edgelets;
    //Other members...
public:
    //The constructor
    Cube(int size) : c_edgelets(12, Edgelet(size - 2)) {}
    
    //Other public members...
};
like image 33
NathanOliver Avatar answered Apr 16 '26 16:04

NathanOliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!