How to keep the implicitly declared aggregate initialization constructor?

孤人 提交于 2019-12-24 13:39:43

问题


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.


回答1:


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.




回答2:


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



回答3:


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



来源:https://stackoverflow.com/questions/34366355/how-to-keep-the-implicitly-declared-aggregate-initialization-constructor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!