11

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)...} {}
6
  • You could store std::unique_ptr<NoDefaultConstructor> instances in the array instead of just NoDefaultConstructor. Commented Jul 7, 2016 at 20:53
  • I explored that idea but I didn't want to use it because I could rather have used an std::vector instead in that case Commented Jul 7, 2016 at 20:53
  • Search for questions on how to initialize data members w/o default constructors. There are plenty of those on SO. Commented Jul 7, 2016 at 20:55
  • 1
    @juanchopanza this is slightly different from the general case Commented Jul 7, 2016 at 21:01
  • Not significantly different. Same thing, really. Commented Jul 7, 2016 at 21:07

2 Answers 2

8

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_ifs

Sign up to request clarification or add additional context in comments.

6 Comments

Is there no way to forward some arguments to this constructor? Is the only way to use variadic templates?
@Curious I don't understand, could you perhaps elaborate?
I wanted the class constructor to accept parameters that would then get forwarded to the array constructor
I don't see the variadic templates.
@Curious To what array constructor? Like I said, std::array has no nontrivial constructors. Are you saying you want Wrapper to exhibit the same construction semantics as the std::array type it wraps? If that's the case, you should make Wrapper into an aggregate as well. coliru.stacked-crooked.com/a/d6affc3571b9c956
|
3

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 }
    { }
};

1 Comment

Edited my question regarding why I was thinking of using variadic arguments, does it make more sense now?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.