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 ?
After "fixing" your example :
I got very clear error message:
This error tells that it is not possible to use the
unique_ptr
's explicit contructor.unique_ptr
's constructor isexplicit
. So you can't create one implicitly with fromnew string{"foo"}
. It needs to be something likeunique_ptr<string>{ new string{"foo"} }
.Which leads us to this
However it may leak if one of the constructors fails. It's safer to use
make_unique
:But...
initializer_list
s always perform copies, andunique_ptr
s are not copyable. This is something really annoying about initializer lists. You can hack around it, or fallback to initialization with calls toemplace_back
.If you're actually managing
string
s with smart pointers and it's not just for the example, then you can do even better: just make avector<string>
. Thestd::string
already handles the resources it uses.