I have a class Obj with a const member i:
class Obj {
const int i;
...
};
But I need to set i to 0 in my move constructor. (Because if i isn't 0, the destructor will delete stuff, and since I moved the object, that will result in a double free)
Is it safe to modify Obj::i in the move constructor like this?
Obj::Obj(Obj &&other) :
i(other.i)
{
std::destroy_at(&other.i);
std::construct_at(&other.i, 0);
}
From how I understand it, it is safe to do this when std::construct_at replaces other.i with a "transparently replaceable object". But I'm not completely sure what the definition means:
(8) An object o1 is transparently replaceable by an object o2 if:
(8.1) the storage that o2 occupies exactly overlays the storage that o1 occupied, and
(8.2) o1 and o2 are of the same type (ignoring the top-level cv-qualifiers), and
(8.3) o1 is not a complete const object, and
(8.4) neither o1 nor o2 is a potentially-overlapping subobject ([intro.object]), and
(8.5) either o1 and o2 are both complete objects, or o1 and o2 are direct subobjects of objects p1 and p2, respectively, and p1 is transparently replaceable by p2.
(https://eel.is/c++draft/basic#life-8)
From my understanding, at least 8.1, 8.2, and 8.3 apply, but I'm not completely sure, and I don't really understand 8.4 and 8.5.
So am I correct in thinking this should work (in C++20), or would this result in undefined behavior?