0

I have the following code:

using TheContainer = std::vector<std::unique_ptr<int>>;

TheContainer GetContainer()
{
    return TheContainer { std::unique_ptr<int>(new int{100}) };
}

int main()
{
    auto container = GetContainer();
}

(Live Sample)

I get a compiler error when I build this:

In file included from main.cpp:3:
In file included from /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/vector:62:
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/stl_construct.h:75:38: error: call to deleted constructor of 'std::unique_ptr<int, std::default_delete<int> >'
    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
                                     ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/stl_uninitialized.h:75:8: note: in instantiation of function template specialization 'std::_Construct<std::unique_ptr<int, std::default_delete<int> >, const std::unique_ptr<int, std::default_delete<int> > &>' requested here
                std::_Construct(std::__addressof(*__cur), *__first);
                     ^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/stl_uninitialized.h:126:2: note: in instantiation of function template specialization 'std::__uninitialized_copy<false>::__uninit_copy<const std::unique_ptr<int, std::default_delete<int> > *, std::unique_ptr<int, std::default_delete<int> > *>' requested here
        __uninit_copy(__first, __last, __result);
        ^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/stl_uninitialized.h:281:19: note: in instantiation of function template specialization 'std::uninitialized_copy<const std::unique_ptr<int, std::default_delete<int> > *, std::unique_ptr<int, std::default_delete<int> > *>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                  ^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/stl_vector.h:1290:11: note: in instantiation of function template specialization 'std::__uninitialized_copy_a<const std::unique_ptr<int, std::default_delete<int> > *, std::unique_ptr<int, std::default_delete<int> > *, std::unique_ptr<int, std::default_delete<int> > >' requested here
            std::__uninitialized_copy_a(__first, __last,
                 ^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/stl_vector.h:377:2: note: in instantiation of function template specialization 'std::vector<std::unique_ptr<int, std::default_delete<int> >, std::allocator<std::unique_ptr<int, std::default_delete<int> > > >::_M_range_initialize<const std::unique_ptr<int, std::default_delete<int> > *>' requested here
        _M_range_initialize(__l.begin(), __l.end(),
        ^
main.cpp:10:12: note: in instantiation of member function 'std::vector<std::unique_ptr<int, std::default_delete<int> >, std::allocator<std::unique_ptr<int, std::default_delete<int> > > >::vector' requested here
    return TheContainer { std::unique_ptr<int>(new int{100}) };
           ^
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/unique_ptr.h:356:7: note: 'unique_ptr' has been explicitly marked deleted here
      unique_ptr(const unique_ptr&) = delete;
      ^
1 error generated.

It's basically saying that it's trying to copy-construct the unique_ptr inside the container. To me, this seems like the vector is being copied, instead of moved. The return expression yields a prvalue, so it should be moved AFAIK.

Why is copy construction even being attempted here? Am I misunderstanding the problem?

EDIT

Upon further inspection it looks like the construction of the temporary vector might be the issue. Still not sure what the root problem is.

void.pointer
  • 24,859
  • 31
  • 132
  • 243
  • 1
    `{ unique_ptr(0).. }` creates an `std::initializer_list` which holds its elements as objects of type `const E`. When the vector internally tries to move the elements into its storage, it will fail since `const` objects cannot be moved from and `unique_ptr` can only be moved. – David G Aug 25 '15 at 16:54
  • The linked answer was helpful, thanks – void.pointer Aug 25 '15 at 17:09

0 Answers0