c++ – Move unique_ptr from vector to deque

Question:

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

Sample code :

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 far as I understand, a move constructor should be used, not a copy constructor, but that doesn't happen.

Answer:

The problem turned out to be in the const qualifier.
In a loop

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

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


A similar error is discussed by Scott Meyers in Effective and Modern C ++ in Section 5.1.

Scroll to Top