Take the 2-minute tour ×

I am trying to initialise an std::vector<std::unique_ptr<std::string>> in a way that is equivalent to an example from Bjarne Stroustrup's C++11 FAQ:

using namespace std;
vector<unique_ptr<string>> vs { new string{"Doug"}, new string{"Adams"} }; // fails
unique_ptr<string> ps { new string{"42"} }; // OK

I can see no reason why this syntax should fail. Is there something wrong with this way of initializing the container?
The compiler error message is huge; the relevant segment I find is below:

/usr/lib/gcc-snapshot/lib/gcc/i686-linux-gnu/4.7.0/../../../../include/c++/4.7.0 /bits/stl_construct.h:77:7: error: no matching function for call to 'std::unique_ptr<std::basic_string<char> >::unique_ptr(std::basic_string<char>&)'

What is the way to fix this error ?

share|improve this question
It is picking up the input iterator ctor –  PlasmaHH Mar 8 '12 at 13:24
Very similar to stackoverflow.com/a/9504162/841108 –  Basile Starynkevitch Mar 8 '12 at 13:28
@PlasmaHH In my actual code I had many entries in the initializer list, so I don't believe this is the issue. –  juanchopanza Mar 8 '12 at 13:38
@juanchopanza: It is the issue in the code you pasted here, which you can easily see by tracing back the instantiation traces. Of course we can't say anything to code you have not presented here. –  PlasmaHH Mar 8 '12 at 13:43
@PlasmaHH That's palusible. The code pasted is the example from the C++11 FAQ I referenced. But if I drop the unique_ptrs and use bare string pointers, the two argument initializer list works fine. –  juanchopanza Mar 8 '12 at 13:53

2 Answers 2

up vote 16 down vote accepted


Which leads us to this

vector<unique_ptr<string>> vs {
    unique_ptr<string>{ new string{"Doug"} },
    unique_ptr<string>{ new string{"Adams"} }

However it may leak if one of the constructors fails. It's safer to use make_unique:

vector<unique_ptr<string>> vs {

But... initializer_lists always perform copies, and unique_ptrs are not copyable. This is something really annoying about initializer lists. You can hack around it, or fallback to initialization with calls to emplace_back.

If you're actually managing strings with smart pointers and it's not just for the example, then you can do even better: just make a vector<string>. The std::string already handles the resources it uses.

share|improve this answer
@Xeo, indeed, stackoverflow.com/questions/6804216/… –  juanchopanza Mar 8 '12 at 13:54
+1 for the links! And no, I am not actually concerned about making a vector of unique_ptrs to string. It is just the example from the FAQ. –  juanchopanza Mar 8 '12 at 14:35
The first example will not leak. The , in the initializer list is a sequence point (in the new, somewhat more cumbersome terminology, in { a, b }, a is sequenced before b). See C++11 §8.5.4/4. It's still a good idea to use make_unique, though. –  James McNellis Mar 9 '12 at 1:28

After "fixing" your example :

#include <vector>
#include <memory>
#include <string>

int main()
    std::vector<std::unique_ptr<std::string>> vs = { { new std::string{"Doug"} }, { new std::string{"Adams"} } }; // fails
    std::unique_ptr<std::string> ps { new std::string{"42"} }; // OK

I got very clear error message:

error: converting to 'std::unique_ptr<std::basic_string<char> >' from initializer list would use explicit constructor 'std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = std::basic_string<char>, _Dp = std::default_delete<std::basic_string<char> >, std::unique_ptr<_Tp, _Dp>::pointer = std::basic_string<char>*]'

This error tells that it is not possible to use the unique_ptr's explicit contructor.

share|improve this answer
Aaaand... that error message tells us nothing. Why is it not possible to use the explicit ctor? –  Xeo Mar 8 '12 at 13:31
@Xeo - which bit of that work explicitly call the ctor? There might be an implicit call there, but that's forbidden. –  Flexo Mar 8 '12 at 13:37
The semantics of a unique_ptr is that it can not be copied, thats the reason the constructor is deleted. But shouldn't std::vector be move-aware and so be able to move from a temporary to the vector? –  hirschhornsalz Mar 8 '12 at 13:41
@drhirch It cannot be copy constructed, but it can be explicitly constructed a from string. So the error is that what is being attempted here is an implicit construction from a string pointer. –  juanchopanza Mar 8 '12 at 15:13
@VJovic I think the error is that it is not possible to implicitly construct the unique_ptr from a string pointer, so I would say that "the error says that it is not possible to implicitly construct unique_ptr because the constructor is explicit. Would you agree? –  juanchopanza Mar 8 '12 at 15:15

Your Answer


