Consider this example:
std::map<int, int> example;
example.insert({ 0, 1 });
example.insert({ 1, 2 });
auto newMap = std::move(example);
example.insert({ 3, 1 }); // I would expect a crash here, yet it still functions OK
In Bjarne Stroustrup's document (link), he explains how std::move and move-semantics behave.
This move() gives its target the value of its argument, but is not obliged to preserve the value of its source. So, for a vector, move() could reasonably be expected to leave its argument as a zero-capacity vector to avoid having to copy all the elements. In other words, move is a potentially destructive read.
I would expect my "example" map to have no valid internal state after the move. Yet I can still insert to it without any problem, why? Is this behavior dependable or is it compiler/platform specific?
For easy copy-paste, here is the code I used (C++14, -O3):
#include <map>
#include <iostream>
int main() {
std::map<int, int> example;
example.insert({ 0, 1 });
example.insert({ 1, 2 });
std::cout << "example\n";
for(auto& pair : example) {
std::cout << pair.first << " " << pair.second << "\n";
}
std::cout << "\nafter move\n";
auto newMap = std::move(example);
std::cout << "newMap\n";
for(auto& pair : newMap) {
std::cout << pair.first << " " << pair.second << "\n";
}
std::cout << "example (empty)\n";
for(auto& pair : example) {
std::cout << pair.first << " " << pair.second << "\n";
}
std::cout << "\ninserting to example\n";
example.insert({ 3, 1 });
example.insert({ 4, 2 });
std::cout << "example\n";
for(auto& pair : example) {
std::cout << pair.first << " " << pair.second << "\n";
}
std::cout << "why can I still insert to example?\n";
}