What to use instead of std :: map :: emplace?

For containers like std::map< std::string, std::unique_ptr< Foo >> , it looks like emplace() is not yet implemented in stdC ++ as of gcc 4.7.2.

Unfortunately, I cannot store Foo directly by value, as this is an abstract superclass.

As a simple but inefficient place owner, I just used std::map< std::string, Foo* > in combination with std::vector< std::unique_ptr< Foo >> to std::vector< std::unique_ptr< Foo >> garbage.

Do you have a workaround that is more efficient and easier to replace after emplace () is available?

+4
source share
2 answers

What do you need emplace() ? Just move it:

 #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 .

As noted in my comment, I am now considering using new in user error code. It should be replaced with make_unique , so you know that your resource cannot flow:

 // 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; } 
+11
source

As a workaround, you can use boost containers that support most C ++ 11 functions even under the C ++ 03 compiler and have the same layout as std containers, and then when you have a function in std , you can simply switch the namespace!

+2
source

All Articles