Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to initialize a member variable of an array type in a template class's member initializer list?

For example, I have a class called Vector that represents a vector and a class called Integer that represents an integer.

class Integer{
public:
   Integer(int v):value_(v){};
private:
   int value_;
};
template<uint32_t Dim>
class Vector{
public:
     Vector(int v[Dim]) 
      ://How to initialize each element of the value_ array here?
     {
     }
private:
     Integer value_[Dim];
}

Since Integer does not have a default constructor, you must initialize each element of the value_ array in the member initialization list of Vector. However, since the length of the array is a template parameter, you cannot directly use something like value_{v[0], v[1], v[2]} to initialize the value_ array.
I’m using c++14.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

As you’ve said, if the size was known, you could write value_{v[0], v[1], v[2]} directly.

Solution A – std::index_sequence

Given that the size isn’t known, you can write something like:

private:
template <std::size_t... I>
Vector(const int(&v)[N], std::index_sequence<I...>)
  : value_{v[I]...} {}

public:
Vector(const int(&v)[Dims])
  : Vector(v, std::make_index_sequence<Dims>{}) {}

Note: this uses a reference to an array so that the size is checked.

The pack expansion v[I]... acts like v[0], v[1], ... for an arbitrary amount Dims of indices (as specified when creating the index sequence with std::make_index_sequence.

Solution B – aggregate initialization

However, since your Vector class only contains an array member, it would be much easier to just have no constructor and rely on aggregate initialization instead.
If you had no constructor, you could write Vector<3>{1, 2, 3} as well.

Solution C – std::array

You could also have a single constructor:

// note: value_ should be std::array as well
Vector(const std::array<int, Dims>& content) : value_{content} {}

std::array has value semantics, and trivializes the problem because you can just copy/move it around like any other object.

Further solutions

See What is the idiomatic way to create a fixed size std::array from a fixed size std::span?. This question is about C++20, but the solutions there are applicable to older versions as well.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading