In the following example I ended the life of s (by calling its dtor.), and after that at the same location I created a new object of the same type S. Since I violated [basic.life]/8.3 (s is const), in order to access the newly created S I have to std::launder its address (see Note 3).
#include <new>
#include <utility>
struct S {
int x;
};
template <class T, class... Pars>
void Recreate(const T& value, Pars&&... pars) {
value.~T();
new(const_cast<T*>(&value)) T(std::forward<Pars>(pars)...);
}
int main() {
const S s(1);
Recreate(s, 2);
return std::launder(&s)->x;
}
Does this program have to return 1 or 2 or is it UB? Or how to std::launder properly? Or is it just ambiguously specified? Notes are non-normative.