Consider the following example:
#include <iostream>
#include <vector>
class A {
public:
A(const A&) = default;
A(A&&) = default;
A& operator=(const A&) = default;
A& operator=(A&&) = default;
A() = default;
~A() {
std::cout << "~A()\n";
}
};
int main() {
std::vector<A> v1;
std::vector<A> v2;
v1.emplace_back();
v1 = std::move(v2);
std::cout << "moved\n";
}
~A()
moved
My question is: Can I rely on std::move
to destruct elements inside v1
? Or, in other words, is the output above guaranteed, or can I get:
moved
~A()
It would be surprising if the latter is possible, but I didn't find a definite answer, and didn't find anything explicit in the standard. That could happen if the move assignment operator is implemented with std::swap
or similar, but I didn't find a solid answer regarding whether that's valid or not.
While swapping would be a valid implementation for move assignment in general, standard library containers have extra requirements. Table 73:
Expression:
a = rv
Return type:X&
Operational semantics: All existing elements ofa
are either move assigned to or destroyed
Assertion/Note pre-/post-condition: Postconditions:a
is equal to the value thatrv
had before this assignment
Complexity: linear
So a swap wouldn't suffice, since that wouldn't move-assign to or destroy the original v1[0]