Implicit or explicitly deleted copy instance

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 ++

+6
source share
1 answer

I already said this in a comment, but since this is the correct answer, I am retelling as one:

A custom constructor has been added (although it has been removed). Therefore, the compiler will not automatically generate a move constructor. Then the compiler returns to copying, which (at your request) obviously cannot do it.

+10
source

Source: https://habr.com/ru/post/959167/


All Articles