Ответ 1
Ваш пример точно так же, как вы его набрали, действительно действителен, но он не позволяет много полезных изменений.
Единственное допустимое преобразование lvalue-to-rval в любой части неактивного члена объединения - это доступ к части общей исходной последовательности этого элемента с активным членом ([class.mem]/23).
Но общая начальная последовательность определяется только для двух структур стандартного макета ([class.mem]/20), и существует довольно много правил для того, что квалифицируется как структура стандартного макета ([класс]/7), Подведение итогов:
-
Класс не может быть полиморфным.
-
У класса может быть не более одного базового класса с одним и тем же типом.
-
У класса может быть нестатический член ссылочного типа.
-
Все нестатические члены класса имеют одинаковое управление доступом.
-
Все нестатические члены, включая унаследованные, сначала объявляются в одном классе.
-
Все базовые классы и нестатические члены, включая унаследованные, подчиняются всем приведенным выше правилам, рекурсивно.
-
Существуют правила, которые говорят, что первый нестатический член структуры стандартного макета имеет тот же адрес, что и структура, и что все нестатические члены союза стандартного макета имеют один и тот же адрес союз. Но если любая комбинация этих правил будет означать, что два объекта одного типа должны иметь один и тот же адрес, содержащая struct/union не является стандартным макетом.
(Пример этого последнего правила:
struct A {}; // Standard-layout
struct B { A a; }; // Standard-layout (and &b==&b.a)
union U { A a; B b; }; // Not standard-layout: &u.a==&u.b.a ??
struct C { U u; }; // Not standard-layout: U is not.
)
Ваши DerivedA
и DerivedB
являются стандартными макетами, поэтому им разрешено иметь общую начальную последовательность. Фактически, эта общая последовательность является единственным членом int
каждого из них, поэтому они на самом деле полностью совместимы с макетами (и поэтому могут быть частью общей исходной последовательности некоторой другой пары структур, содержащей эти два).
Однако одна из самых сложных вещей - это правило о всех членах, принадлежащих к одному классу. Если вы добавите какой-либо нестатический член в DerivedA
и/или DerivedB
, даже если вы добавите к нему один и тот же тип, измененные структуры (s) уже не являются стандартными макетами, поэтому нет обычной начальной последовательности. Это ограничивает большинство реалистичных причин, по которым вы хотели бы использовать наследование в этом шаблоне.