Что я знаю, так это то, что деструктор всегда должен вызываться при использовании нового размещения.
Да, за исключением случаев, когда тип тривиально разрушаем.
В этом случае вы должны уничтожить ранее построенный объект перед размещением нового:
X x{1};
x.~X();
try {
new (&x) X{2};
} catch(...) {
std::abort(); // no way to recover
}
Автоматическая переменная нетривиально разрушаемого типа не должна выходить за пределы области действия в разрушенном состоянии.Если сработает конструктор, поведение будет неопределенным.Повторное использование памяти нетривиального объекта не рекомендуется.
Безопаснее повторно использовать память тривиального объекта:
alignas(alignof(X)) std::byte arr[sizeof(X)];
new (arr) X{2};
x.~X();