3

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;
}

Live demo.

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.

Dr. Gut
  • 2,053
  • 7
  • 26
  • 2
    You need to look a bit below at [basic.life]/10. – user17732522 May 31 '23 at 00:18
  • 2
    Thanks. [\[basic.life\]/10](https://timsong-cpp.github.io/cppwp/n4868/basic.life#10) says it's UB to reuse the storage of a const automatic object. So the answer is UB. – Dr. Gut May 31 '23 at 00:33

0 Answers0