Делегирование конструктора C++11 с агрегатной инициализацией

Можно ли вызвать агрегатную инициализацию в моем собственном определении ctor по умолчанию?

GCC жалуется на "ошибку: конструктор делегирует себя" с кодом ниже:

struct X {
  int x, y, z, p, q, r;
  X(): x{}, y{}, z{}, p{}, q{}, r{} { }  // cumbersome
//X(): X{} { }  // the idea is nice but doesn't compile
};

я использую memset(this, 0, sizeof(*this)) в корпусе ctor на данный момент.

3 ответа

Одним из способов было бы обмануть разрешение перегрузки следующим образом:

struct X {
  int x, y, z, p, q, r;
  X(int) : x{}, y{}, z{}, p{}, q{}, r{} { }
  X() : X(0) { }
};

Другой способ - использовать инициализацию члена класса по умолчанию:

struct X {
  int x = 0, y = 0, z = 0, p = 0, q = 0, r = 0;
};

В вашем конкретном примере вы также можете сделать:

struct X {
  std::array<int, 6> vars{};
};

Вы можете использовать CRTP для этого.

template<class C>
struct ZeroInitialized
{
    ZeroInitialized() { memset((C*)this, 0, sizeof(C)); }
};


struct A : ZeroInitialized<A>
{
    int x, y, z, p, q, r;
};

Но я не даю никаких гарантий, что это безопасно.

Использовать шаблон фабрики - переместите тело вашего конструктора в отдельный класс:

struct X {
  int x, y, z, p, q, r;
};

struct XFactory {
  X create();
};

X XFactory::create()
{
   X x{};
   // do needed modification
   return x;
}

Хотя я бы всегда предпочел фабричный шаблон - есть и другой способ, более соответствующий вашим явным потребностям - определите конструктор по умолчанию для каждого из ваших данных члена:

template <typename T>
struct DefaultConstructibleData
{
   T data;
   DefaultConstructibleData() data{} {} 
};

И использовать это:

struct X {
  DefaultConstructibleData<int> x, y, z, p, q, r;
  X() 
  {         
       // do whatever you needs to do
       // all x,y,... are already constructed to their defaults
  }
};
Другие вопросы по тегам