В частности, я хотел бы иметь возможность использовать полиморфизм без выделения кучи во встроенном контексте (то есть без динамического выделения).Похоже, меня беспокоит то, что доступ к члену base
, в то время как x
или y
являются «активными» в объединении, кажется, является примером наказания типов, даже если они имеют один и тот же начальный заголовок (и структуру vtable).).Будет ли приведенный ниже код рассматриваться как определенное поведение?
#include <iostream>
#include <new>
using namespace std;
struct Base {
virtual const char *foo() { return "base"; }
};
struct X: public Base {
const char *foo() override { return "d1"; }
};
struct Y: public Base {
const char *foo() override { return "d2"; }
};
union DerivedAny {
DerivedAny() {}
Base& get() { return *launder(&b); }
Base b = {};
X x;
Y y;
};
DerivedAny objs[3];
int main() {
new (&objs[1].x) X;
new (&objs[2].y) Y;
cout << objs[0].get().foo() << endl;
cout << objs[1].get().foo() << endl;
cout << objs[2].get().foo() << endl;
}
Я скомпилировал его как с GCC, так и с Clang, и они должны отображать ожидаемый результат в обоих случаях:
base
d1
d2