Copy/move requirements for the key/value types in a std::map?

c++, c++11

Solution

Copy-assignment of one map to another requires copying each item. Since you cannot copy items, you cannot copy-assign the maps.

Whether the actual map object is empty at runtime is immaterial, since these are purely static considerations, determined entirely by the types of the objects.

(It's like asking why `sin(0)` requires a floating point unit when clearly the result is an integer.)

Moving the entire map, on the other hand, is fine because the container is node-based and no actual values are mutated, just the nodes are. In fact, move-constructing or move-assigning node based containers doesn't require the elements to be copyable or movable or assignable at all.

(This should be true for all containers that manage dynamic memory in a suitable fashion, such as via `std::allocator<value_type>`, but it would of course not be true for something like `std::array`, and it would be interesting whether or not it would hold for `std::dynarray`, and as @Jonathan Wakely noted, if the allocation scheme isn't able to move nodes wholesale.)

Problem

This code confuses me: ``` struct foo { int i; foo(int j) : i(j) {} foo(const foo &) = delete; foo(foo &&) = delete; foo &operator=(const foo&) = delete; foo &operator=(foo&&) = delete; }; bool operator<(const foo &f1, const foo &f2) { return f1.i < f2.i; } int main(int argc, char **argv) { std::map<foo,int> f; std::map<foo,int> f2 = f; //error (as expected) std::map<foo,int> f3 = std::move(f); //no error (why?) return 0; } ``` Because I get no error there, it seems like when moving a map no key object is created (not even for moving another key object into it). Why not? Can I rely on this behavior according to the C++11 standard? More generally, what copying/moving requirements does a `std::map` place on the key and value types and under what conditions?

Original source