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)...} {}
No default constructor is created for a class that has any constant or reference type members.
You should define it in class CheckBook constructor. Show activity on this post. The correct way to build an array of objects having no default constructor is to use the placement new syntax to separate the allocation of the array and the construction of the objects.
Answer: C++ Empty constructor necessity depends upon class design requirements. We know that C++ class constructor is called when we create an object of a class. If a class is not required to initialize its data member or does not contain data member, there is no need to write empty constructor explicitly.
Java doesn't require a constructor when we create a class. However, it's important to know what happens under the hood when no constructors are explicitly defined. The compiler automatically provides a public no-argument constructor for any class without constructors. This is called the default constructor.
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
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 }
{ }
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With