Kan Li
Kan Li

Reputation: 8797

How to keep the implicitly declared aggregate initialization constructor?

Suppose I have a class like this:

struct X {
  char buf[10];
};
X x{"abc"};

This compiles. However, if I add user defined constructors to the class, this implicitly declared aggregate initialization constructor will be deleted:

struct X {
  char buf[10];
  X(int, int) {}
};
X x{"abc"}; // compile error

How can I declare that I want default aggregate initialization constructor, just like that for default constructor X()=default? Thanks.

Upvotes: 2

Views: 513

Answers (3)

Nicol Bolas
Nicol Bolas

Reputation: 473222

There is no "default aggregate initialization constructor".

Aggregate initialization only happens on aggregates. And aggregates are types that, among other things, don't have (user-provided) constructors. What you're asking for is logically impossible.

The correct means of doing what you want is to make a factory function to construct your type in your special way. That way, the type can remain an aggregate, but there's a short-hand way for initializing it the way you want.

You give a type a constructor when you want to force users to call a constructor to construct it. When you don't, you just use factory functions.

Upvotes: 6

RichardBruce
RichardBruce

Reputation: 671

It wont be "default" in anyway (and I agree with Nicol Bolas), but I think you can achieve, almost, what you want with an std::initialize_list. Untested example below

struct foo {
  foo (std::initializer_list<int> it)
  {
     assert(it.size() < 6);
     int idx = 0;
     for (auto i=it.begin(); i!=it.end();++i)
          data[idx++]=*i;
  }
  int data[5];
};

foo bar {10,20,30,40,50};

Upvotes: 1

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42889

You could provide another constructor that takes as argument a string like below:

struct X {
  char buf[10];
  X(int, int) {}
  X(char const *str) {
    strncpy(buf, str, 10);
  }
};

Live Demo

Upvotes: 0

Related Questions