In C++11, \"move semantics\" was introduced, implemented via the two special members: move constructor and move assignment. Both of these operations leave the moved-fro
In the "universe of move operations" there are four possibilities:
target source
is is left
----------------------------------------------------------
constructed <-- constructed // C++11 -- move construction
constructed <-- destructed
assigned <-- constructed // C++11 -- move assignment
assigned <-- destructed
Each of these operations is useful! std::vector
alone could make use of the first three. Though note:
X x1, x2;
if (sometimes)
{
x1 = std::move(x2);
}
// Is x2 moved-from here?
The 2nd and 4th can be emulated by the 1st and 3rd respectively, by simply manually calling the destructor on the source after the operation.
The 1st and 3rd are crucial. Algorithms such as std::swap
and std::sort
regularly need both of these operations. These algorithms do not need to destruct any of their input objects — only change their values.
Armed with this knowledge, in the 2001-2002 time frame I focused my efforts on the two operations that left their source constructed because these two operations would have the largest (positive) impact on what was then C++98. I knew at the time that if I did not curtail the ambitions of this project, that it would never succeed. Even curtailed, it was borderline too-ambitious to succeed.
This curtailment is acknowledged in the original move semantics proposal under the section titled "Destructive move semantics".
In the end, we simply gave up on this as too much pain for not enough gain. However the current proposal does not prohibit destructive move semantics in the future. It could be done in addition to the non-destructive move semantics outlined in this proposal should someone wish to carry that torch.
For more details on what one can do with a moved-from object, see https://stackoverflow.com/a/7028318/576911