I have a class with a member array. The length is a constant, but this constant is not known until compile time (In my actual code, this constant is defined differently for different compilation targets). The type of the array is a class with no default constructor.
#define CONSTANT 2
class Data {
public:
Data(int number){}
};
class DemoClass {
private:
Data _member[CONSTANT];
public:
DemoClass():
_member{
Data(0),
Data(0)
}
{
// stuff
}
};
In this example, I can set _member
using the initializer list. However, if the value of COSNTANT
changes, I have to change that initializer list.
In theory, changing DemoClass
to have a default constructor that calls the other constructor with an argument of 0
would work for my case, because I will always call the Data
constructor with 0
. However, I cannot change DemoClass
because it is in an external library.
One solution I've considered is creating the following class:
class CustomData : public Data {
public:
CustomData() : Data(0){}
};
This works, but it seems a bit complicated. Is there a simpler way to initialize this array?
I found the answer to your problem here. So, in your case this solution should be applied like that:
#include <utility>
#include <array>
#define CONSTANT 2
class Data {
public:
Data(int number){}
};
template<typename T, size_t...Ix, typename... Args>
std::array<T, sizeof...(Ix)> repeat(std::index_sequence<Ix...>, Args &&... args) {
return {{((void)Ix, T(args...))...}};
}
template<typename T, size_t N>
class initialized_array: public std::array<T, N> {
public:
template<typename... Args>
initialized_array(Args &&... args)
: std::array<T, N>(repeat<T>(std::make_index_sequence<N>(), std::forward<Args>(args)...)) {}
};
class DemoClass {
private:
initialized_array<Data, CONSTANT> _member;
public:
DemoClass():
_member(1234)
{
// stuff
}
};
Then your _member
is statically allocated fixed size array. That approach is a bit complicated though, so maybe someone can provide a cleaner solution.
I've accepted this answer because it does answer my question as written. However, it really just tells me that I should just use a simpler solution, like finding a way to implement a default constructor on
Data
. Seeing all of these answers kind of made me realize why there's no simple one-line solution to initializing an array of objects without default constructors.