I recently experienced some weird behavior in my C ++ 11 code.
I have a class that is only accessible for moving:
class only_move { public: only_move() : value(0) {} only_move(int value) : value(value) {} only_move(const only_move&) = delete; only_move& operator=(const only_move&) = delete; only_move(only_move&&) = default; only_move& operator=(only_move&&) = default; int value; };
And I have another class containing an only_move object:
class has_only_move_member { public: has_only_move_member() = delete; has_only_move_member(only_move&& value) : member(std::move(value)) {} only_move member; };
If I understood this correctly, this means that has_only_move_member cannot be copied, since the only_move member cannot be copied. This means that has_only_move_member(const has_only_move_member&) is deleted implicitly. Let me check this out:
has_only_move_member object(only_move(5)); has_only_move_member copy_of_object(object);
As expected, it prints:
error: use of deleted function 'has_only_move_member::has_only_move_member(const has_only_move_member&)' note: 'has_only_move_member::has_only_move_member(const has_only_move_member&)' is implicitly deleted because the default definition would be ill-formed: class has_only_move_member
Ok, so I switched and placed the has_only_move_member instances in std::map . Since they do not have a copy constructor, I moved them to it:
has_only_move_member object(only_move(5)); std::map<int, has_only_move_member> data; data.emplace(5, std::move(object));
So far so good. It works like a charm.
But I had an idea. How to be more explicit and explicitly remove the has_only_move_member copy has_only_move_member . So I wrote the has_only_move_member class:
has_only_move_member(const has_only_move_member&) = delete;
After that, the same code above, there I moved the objects to the map, giving me an error:
/usr/include/c++/4.8/bits/stl_pair.h:134:45: error: use of deleted function 'has_only_move_member::has_only_move_member(const has_only_move_member&)'
Yes, of course, he retired, but why is there such a gap between implicit and explicit deletion?
I get the same behavior with g ++ 4.8.2 and clang 3.4-rc1 on Debian with libstdC ++ and the latest apple-clang-llvm 4.0 on Mac OS X 10.9 with libC ++