The "Using placement new to update a reference member?" question shows this example (simplified):
struct Foo { int& v_; };
int a, b;
Foo f{a};
new (&f) Foo{b};
assert(&f.v_ == &a); // UB
Accessing f
through its original name is definitely UB as explained by T.C. in the linked question. I know that std::launder
can be used to work around this:
assert(&std::launder(&f)->v_ == &a); // OK, will fire the assert
But what about using the pointer returned by placement new
? I.e.
auto p = new (&f) Foo{b};
assert(&(p->v_) == &a); // UB? OK?
In this case, we're not referring to the object through its original name, but through whatever placement new
returned.
Is this undefined behavior or allowed by the Standard?