Description
Should rule C.65: Make move assignment safe for self-assignment apply if a type has stl members?
Rule C.20: If you can avoid defining default operations, do shows an example using stl types without protecting for self-move:
// From the example in C.20 'If you can avoid defining default operations, do'
struct Named_map {
public:
// ... no default operations declared ...
string name;
map<int, int> rep;
};
int main()
{
Named_map nm{"Four", {{4,4}}};
cout << "Pre-move: " << nm.name << ", " << nm.rep[4] << "\n";
nm = move(nm); // self-move
cout << "Post-move: " << nm.name << ", " << nm.rep[4] << "\n";
}
The above outputs:
Pre-move: Four, 4
Post-move: , 0
which happens becuse stl types generally only guarantee 'valid but unspecified' for self-move. Which should take precedence C.20 or C.65? To me, C.20 should take precedence because the rule-of-zero makes code simpler, self-moves that would cause a problem are likey bugs anyway, and developers may accidently introduce bugs when implemeting a safe self-move.
I made a previous attempt with #1938 but that was too aggresive. Maybe the PR could be reworded to preserve values for self move with an exception for stl members?