Reputation: 21510
So let's assume I have the following class
class NoDefaultConstructor {
NoDefaultConstructor() = delete;
...
};
And I have another class which has an array of type NoDefaultConstructor
and other members
class Wrapper {
std::array<NoDefaultConstructor, 2> arr;
...
};
How can I initialize the array in the constructor for Wrapper
(maybe in the initializer list using an std::intializer_list
)?
More specifically, is the only way I can pass on arguments to the array constructor in the initializer list for Wrapper
to have a construct similar to the following? I was thinking of doing this because the size of the array might change in the future.
template <typename... Values>
Wrapper(Values&&... values) : arr{std::forward<Values>(values)...} {}
Upvotes: 11
Views: 7431
Reputation: 119124
std::array
is required to be an aggregate. Therefore it has no nontrivial constructors, but can be initialized using aggregate initialization. Note that aggregate initialization involves a braced-init-list (that is, a brace-enclosed list of initializers) but not an std::initializer_list
object.
class Wrapper {
public:
Wrapper() : arr {MakeNoDefaultConstructor(123),
MakeNoDefaultConstructor(456)} {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ braced-init-list
private:
std::array<NoDefaultConstructor, 2> arr;
};
EDIT A constructor with variadic arguments could be possible here like so
#include <array>
struct NoDefault {
NoDefault() = delete;
NoDefault(int) {}
};
struct Wrapper {
template <typename... Args>
Wrapper(int b_in, Args&&... args) : b{b_in}, a{args...} {}
int b;
std::array<NoDefault, 3> a;
};
int main() {
std::array<NoDefault, 2> a {12, 34};
Wrapper w {23, 12, 34, 19};
}
This of course can be further tightly constrained by adding enable_if
s
Upvotes: 8
Reputation: 171263
How can I initialize the array in the constructor for Wrapper (maybe in the initializer list using an std::intializer_list)?
Just as you would for any other member, but use uniform initialization because std::array
doesn't have any constructors.
More specifically, is the only way I can pass on arguments to the array constructor in the initializer list for Wrapper to have a construct similar to the following?
No, why would you need to use a variadic templates for a fixed number of arguments?
Just ... write the constructor, with arguments:
class Wrapper {
std::array<NoDefaultConstructor, 2> arr;
Wrapper(const NoDefaultConstructor& a, const NoDefaultConstructor& b)
: arr{ a, b }
{ }
};
Upvotes: 3