Я недавно прочитал описание конструкторов по умолчанию для объединений: Конструктор по умолчанию
Существует следующее правило:
Blockquote Удален неявно объявленный конструктор по умолчанию: [...] T является объединением по крайней мере с одним вариантным членом с нетривиальным конструктором по умолчанию, и ни один вариантный член T не имеет инициализатора элемента по умолчанию. [...]
ТогдаЯ решил выполнить упражнение и проверить правило.
struct Member {
public:
// Member() : mX(0) {}
virtual int GetX() {
return mX;
}
int mX;
};
union DefaultConstructor {
int mA;
Member mMember;
int GetA();
};
При использовании gcc v5.3.1 (я знаю, что он довольно старый) я получаю ожидаемую ошибку:
> ../src/DefaultConstrcutors.cpp: In function ‘void
> Test_DefaultConstructors()’: ../src/DefaultConstrcutors.cpp:26:22:
> error: use of deleted function
> ‘DefaultConstructor::DefaultConstructor()’ DefaultConstructor foo;
> ^ In file included from ../src/DefaultConstrcutors.cpp:19:0:
> ../src/DefaultConstructors.h:155:7: note:
> ‘DefaultConstructor::DefaultConstructor()’ is implicitly deleted
> because the default definition would be ill-formed: union
> DefaultConstructor {
> ^ ../src/DefaultConstructors.h:157:10: error: union member ‘DefaultConstructor::mMember’ with non-trivial ‘Member::Member()’
> Member mMember;
> ^
OkТаким образом, согласно правилу, если я предоставлю инициализатор элемента по умолчанию для варианта элемента, то он должен скомпилироваться.Поэтому я изменил определение объединения на:
union DefaultConstructor {
int mA = 0;
Member mMember;
int GetA();
};
И теперь он должен скомпилироваться, но я получил ту же ошибку.
Следующим шагом было предоставление вместо инициализатора по умолчанию для mMember.мА (только один вариантный элемент объединения может иметь инициализатор по умолчанию).
union DefaultConstructor {
int mA;
Member mMember{};
int GetA();
};
Теперь он компилируется.
Вопрос: почему он не компилировался во втором случае, когда у mA был инициализатор по умолчанию?Согласно упомянутому правилу это должно быть возможно.Какое более похожее правило представлено здесь: Объявление объединения
Если объединение содержит нестатический член данных с нетривиальным конструктором по умолчанию, конструктором по умолчанию объединения являетсяудаляется по умолчанию, если вариантный член объединения не имеет инициализатора элементов по умолчанию.
У кого-нибудь есть идеи, почему он не работает?
Greetings, Piotr