A container of unique_ptr seems to make little sense: you cannot use it with initializer lists and I failed to iterate through the container (workarounds below). Am I misunderstanding something? Or when does it make sense to use unique_ptr and STL containers?
#include <memory>
#include <vector>
using namespace std;
struct Base { void go() { } virtual ~Base() { } };
// virtual ~Base() = default; gives
// "declared virtual cannot be defaulted in the class body" why?
class Derived : public Base { };
int main() {
//vector<unique_ptr<Base>> v1 = { new Derived, new Derived, new Derived };
//vector<shared_ptr<Base>> v2 = { new Derived, new Derived, new Derived };
vector<Base*> v3 = { new Derived, new Derived, new Derived };
vector<shared_ptr<Base>> v4(v3.begin(), v3.end());
vector<unique_ptr<Base>> v5(v3.begin(), v3.end());
for (auto i : v5) { // works with v4
i->go();
}
return 0;
}
The following questions helped me find these workarounds:
Should be
Else you’ll try to copy the current element.
Also, you can’t use an initializer list like that, because the constructors of
std::unique_ptrandstd::shared_ptrare markedexplicit. You need to do something like this:And this is a Good Thing™, because otherwise you might leak memory (if one of the later constructors throws, the former ones aren’t yet bound to the smart pointers). The tip-toeing for the
unique_ptris necessary, because initializer lists copy their arguments, and sinceunique_ptrs aren’t copyable, you’d get a problem.That said, I use a
std::map<std::string, std::unique_ptr<LoaderBase>>for a dictionary of loaders in one of my projects.