It is necessary to transfer an object of type std::unique_ptr from a vector to dek.

Code example :

 using UPtr = std::unique_ptr<int>; std::deque<UPtr> d; std::vector<UPtr> v; for (int i = 0; i < 5; ++i) { v.emplace_back(new int(i)); } for (const auto& item : v) { d.emplace_front(std::move(item)); } 

But suddenly a compilation error occurs:

 error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]' { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } ^ In file included from /usr/include/c++/5/memory:81:0, from prog.cpp:4: /usr/include/c++/5/bits/unique_ptr.h:356:7: note: declared here unique_ptr(const unique_ptr&) = delete; 

As I understand it, a relocation constructor should be used, not a replicator, but this does not happen.

    1 answer 1

    The problem was in the const qualifier.
    In cycle

     for (const auto& item : v) { d.emplace_front(std::move(item)); } 

    the item variable has the type const std::unique_ptr<int>& , respectively, by calling std::move we get the type const std::unique_ptr<int>&& . There is no relocating constructor that would accept this type, so the compiler uses the copy constructor, which leads to an error.


    A similar error was considered by Scott Meyers in the book "Efficient and Modern C ++" in section 5.1.

    • Um .. And what is the final decision? - Qwertiy
    • Remove the qualifier 'const' ;-) - Pavel Parshin
    • @Qwertiy obviously need to remove const . - αλεχολυτ
    • @alexolut, yes, I’ve been too smart about something. For some reason I thought that const is needed. A link is needed, not him. - Qwertiy
    • 2
      I would say that the problem is wider than in the absence of a constructor. As soon as something moves - somehow! - this is something changing, which means that such an object cannot be const in principle. - Harry