Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what to use in place of std::map::emplace?

Tags:

c++

std

c++11

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?

like image 781
kfmfe04 Avatar asked Dec 12 '22 19:12

kfmfe04


1 Answers

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;
}
like image 71
GManNickG Avatar answered Dec 20 '22 18:12

GManNickG