Destroy and then construct new object using the same variable
Sometimes it's nice to start over. In C++ I can employ this following simple manoeuvre:
{
T x(31, Blue, false);
x.~T(); // enough with the old x
::new (&x) T(22, Brown, true); // in with the new!
// ...
}
At the end of the scope, the destructor will run once again and all seems well. (Let's also say T
is a bit special and doesn't like being assigned, let alone swapped.) But something tells me that it's not always without risk to destroy everything and try again. Is there a possible catch with this approach?
Solution 1:
I think the only way to make this really safe to use is to require the called constructor to be noexcept
, for example by adding a static_assert
:
static_assert(noexcept(T(22, Brown, true)), "The constructor must be noexcept for inplace reconstruction");
T x(31, Blue, false);
x.~T();
::new (&x) T(22, Brown, true);
Of course this will only work for C++11.
Solution 2:
If T
's constructor throws on the second construction, you got a problem. If you like brute-force approaches, check this:
T x(31, Blue, false);
x.~T();
const volatile bool _ = true;
for(;_;){
try{
::new (&x) T(22, Brown, true);
break; // finally!
}catch(...){
continue; // until it works, dammit!
}
}
It even provides the strong exception guarantee!
On a more serious note, it's like stepping on a landmine, knowing it will go off if you move your foot...
And there actually is a way around the undefined behaviour of the double destruction here:
#include <cstdlib>
T x(31, Blue, false);
x.~T();
try{
::new (&x) T(22, Brown, true);
}catch(...){
std::exit(1); // doesn't call destructors of automatic objects
}