3

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?

2

2 Answers 2

7

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)) {}
Sign up to request clarification or add additional context in comments.

2 Comments

Depending on what happens inside Edgelet constructor, might want to construct it in-place instead of copying.
I have not studied C++ upto templates but it seems I have no choice but to learn them first to implement this thing. Anyways thank you for the answer.
3

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...
};

3 Comments

Is there any method to do it with std::array? As the size is compile-time constant the use of std::array is more natural instead of std::vector.
@Jatin Jarod42 just posted a way to do this with a std::array.
Could also be a use case for boost::static_vector

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.