Search code examples
c++c++11unique-ptrinitializer-list

Unable to construct a vector<std::unique<...>> using an initialiser list


I'm trying to initailise a vector of unique_ptr using an initialiser list and it fails with a compiler error. Which seems odd as it looks similar to a number of examples that I've seen.

std::vector<std::unique_ptr<std::string>> v{
    std::unique_ptr<std::string>{new std::string{"foo"}}
};

Fails with a compiler error.

.../memory:1645:31: error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<std::__1::basic_string<char>, std::__1::default_delete<std::__1::basic_string<char> > >'
        ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
...
...47: note: in instantiation of member function 'std::__1::vector<std::__1::unique_ptr<std::__1::basic_string<char>, std::__1::default_delete<std::__1::basic_string<char> > >, std::__1::allocator<std::__1::unique_ptr<std::__1::basic_string<char>, std::__1::default_delete<std::__1::basic_string<char> > > > >::vector' requested here
std::vector<std::unique_ptr<std::string>> v{
                                          ^

Solution

  • std::unique_ptr has no copy constructor. You create an instance and then ask the std::vector to copy that instance during initialisation.

    error: call to implicitly-deleted copy constructor of 'std::__1::unique_ptr<std::__1::basic_string<char>, std::__1::default_delete<std::__1::basic_string<char> > >'
            ::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
    

    The class satisfies the requirements of MoveConstructible and MoveAssignable, but not the requirements of either CopyConstructible or CopyAssignable.

    The following works with the new emplace calls. However fails to utilise initialisation lists.

    std::vector< std::unique_ptr< std::string > > v;
    v.emplace_back( new std::string{ "foo" } );
    

    See using unique_ptr with standard library containers for further reading.