1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| #include <new> #include <cstddef> #include <cassert> #include <iostream>
struct X { const int n; int m; };
struct Y { int z; };
struct A { virtual int transmogrify(); };
struct B : A { int transmogrify() override { new(this) A; return 2; } };
int A::transmogrify() { new(this) B; return 1; }
static_assert(sizeof(B) == sizeof(A));
int main() { X* p = new X{ 3, 4 }; std::cout << "p->m:" << p->m << ", p->n:" << p->n << "\n"; const int a = p->n; std::cout << "a:" << a << "\n"; X* np = new (p) X{ 5, 6 }; std::cout << "p->m:" << p->m << ", p->n:" << p->n << "\n"; std::cout << "np->m:" << np->m << ", np->n:" << np->n << "\n"; const int b = p->n; const int c = p->m; std::cout << "b:" << b << "\n"; std::cout << "c:" << c << "\n"; const int d = std::launder(p)->n; std::cout << "d:" << d << "\n"; const int e = np->n; std::cout << "e:" << e << "\n"; A i; int n = i.transmogrify(); std::cout << "n:" << n << "\n"; int m = std::launder(&i)->transmogrify(); std::cout << "m:" << m << "\n";
assert(m + n == 3);
alignas(Y) std::byte s[sizeof(Y)]; Y* q = new(&s) Y{ 2 }; const int f = reinterpret_cast<Y*>(&s)->z; std::cout << "f:" << f << "\n";
const int g = q->z; const int h = std::launder(reinterpret_cast<Y*>(&s))->z; std::cout << "g:" << g << "\n"; std::cout << "h:" << h << "\n";
return 0; }
|