Initializing container of unique_ptrs from initializer list fails with GCC 4.7

unique_ptr‘s constructor is explicit. So you can’t create one implicitly with from new string{"foo"}. It needs to be something like unique_ptr<string>{ new string{"foo"} }.

Which leads us to this

// not good
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:

// does not work
vector<unique_ptr<string>> vs {
     make_unique<string>("Doug"),
     make_unique<string>("Adams")
};

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.

Leave a Comment