Это:
auto p = new (&f) Foo{b};
assert(&(p->v_) == &a); // UB? OK?
Четко определено.Утверждение сработает.new
создает новый объект, а p
указывает на этот новый объект.Это все прекрасно.Мы повторно используем хранилище f
, и в [basic.life] есть много правил о том, что нормально, а что нет, о том, как можно использовать старые имена- существуют правила о том, как вы можете использовать f
, предыдущие указатели на f
и т. д. Вы не можете повторно использовать &f
без launder
.Там правила о том, как и когда вы можете вызывать деструкторы в этом случае, или как насчет повторного использования хранилища для статического хранилища или константных объектов - здесь тоже ничего не важно.
Но p
- это новая вещь - она просто относится к новому объекту.И p->v_
- это новый int&
, который вы создали, который относится к b
.Это не тот же объект, что и a
, поэтому указатели сравниваются неравно.