For containers such as std::map< std::string, std::unique_ptr< Foo >>
, it looks like emplace()
has yet to be implemented in stdc++ as of gcc 4.7.2.
Unfortunately, I can't store Foo directly by value as it is an abstract super-class.
As a simple, but inefficient, place-holder, I've just been using std::map< std::string, Foo* >
in conjunction with a std::vector< std::unique_ptr< Foo >>
for garbage collection.
Do you have a interim solution that is more efficient and more easily replaced once emplace() is available?
What do you need emplace()
for? Just move it in:
#include <iostream>
#include <map>
#include <memory>
#include <string>
struct Foo
{
virtual ~Foo() = default;
virtual std::string name() const = 0;
};
struct Bar : Foo
{
std::string name() const { return "Bar"; }
};
int main()
{
std::map<std::string, std::unique_ptr<Foo>> m;
std::unique_ptr<Foo> p(new Bar());
m.insert(std::make_pair("a", std::move(p)));
std::cout << m["a"]->name() << std::endl;
}
In fact, you should not use emplace
with unique_ptr
's.
As noted in my comment there, I now consider the use of new
in user code an error. It should be replaced with make_unique
, so you know your resource cannot possibly leak:
// will be in std:: someday
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
int main()
{
std::map<std::string, std::unique_ptr<Foo>> m;
m.insert(std::make_pair("a", make_unique<Bar>()));
std::cout << m["a"]->name() << std::endl;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With