Делегирование конструктора 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
}
};