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 initializer 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.
As you've said, if the size was known, you could write
value_{v[0], v[1], v[2]}directly.Solution A -
std::index_sequenceGiven that the size isn't known, you can write something like:
Note: this uses a reference to an array so that the size is checked.
The pack expansion
v[I]...acts likev[0], v[1], ...for an arbitrary amountDimsof indices (as specified when creating the index sequence withstd::make_index_sequence.Solution B - aggregate initialization
However, since your
Vectorclass 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 writeVector<3>{1, 2, 3}as well.Solution C -
std::arrayYou could also have a single constructor:
std::arrayhas 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.