What can we use if we want to copy from one region to another, and we do not know at compile time if the ranges can intersect or in which direction a coincidence can occur?
This is not a coherent concept.
After the copy operation, you will have two objects. And each object is defined by a separate and separate memory area. You cannot have objects that overlap this way (you can have subobjects, but the type of an object cannot be its own subobject). And therefore, it is impossible to copy an object on top of the part itself.
Moving an object on top of itself is also not logically consistent. What for? Because moving is fiction in C ++; after moving, you still have two perfectly functional objects. A move operation is simply a destructive copy that steals resources belonging to another object. It still exists, and it is still a viable object.
And since the object cannot intersect with another object, this is again impossible.
Trivially copied types go around this because they are just blocks of bits, without destructors or specialized copy operations. Therefore, their life is not as harsh as that of others. A type that cannot be trivially copied cannot do this because:
Experience with memmove suggests that in this case there may be a solution (and possibly also for iterators in adjacent containers).
This is not possible and generally not desirable for types that are not trivially copied in C ++.
The rules of trivial copyability are that the type does not have non-trivial copy / move / assign constructor operators, and there is no non-trivial destructor. The trivial constructor / purpose of copy / move is nothing more than memcpy, and the trivial destructor does nothing. And therefore, these rules effectively guarantee that a type is nothing more than a "block of bits." And one “block of bits” is no different from the other, so copying it through memmove is a legal construct.
If the type has a real destructor, then the type supports some invariant, which requires real efforts to maintain. It can free a pointer or free a file descriptor or whatever. Given this, it makes no sense to copy bits, because now you have two objects that reference the same pointer / file pointer. This is bad because a class usually wants to control how it is handled.
This problem cannot be resolved if the class itself is not involved in the copy operation. Different classes have different behaviors regarding the management of their internal elements. In fact, this is the whole purpose of objects that have copy constructors and assignment operators. So that the class itself can decide how to maintain the sanity of its own condition.
And it doesn't even have to be a pointer or file. Each instance of the class may have a unique identifier; such a value is generated during construction, and it is never copied (new copies get new values). So that you violate this restriction with memmove , you will leave your program in an undefined state because you will have code that expects such identifiers to be unique.
Thus, memmove ing for non-trivial copied types gives undefined behavior.