4

对于诸如 的容器,从 gcc 4.7.2 开始std::map< std::string, std::unique_ptr< Foo >>,它似乎emplace()还没有在 stdc++ 中实现。

不幸的是,我不能直接按值存储 Foo,因为它是一个抽象的超类。

作为一个简单但低效的占位符,我一直std::map< std::string, Foo* >在与std::vector< std::unique_ptr< Foo >>垃圾收集结合使用。

一旦 emplace() 可用,您是否有一个更有效且更容易替换的临时解决方案?

4

2 回答 2

11

你需要emplace()什么?只需将其移入:

#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;
}

事实上,你不应该使用emplacewith unique_ptr's

正如我在那里的评论中所指出的,我现在认为new在用户代码中使用是一个错误。它应该替换为make_unique,因此您知道您的资源不可能泄漏:

// 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;
}
于 2012-12-09T06:58:48.503 回答
2

作为一种解决方法,您可以使用boost即使在 C++ 03 编译器下也支持大多数 C++ 11 功能的容器,并且具有与容器相同的布局std,然后当您拥有该功能时,std您可以切换名称空间!

于 2012-12-09T05:35:27.607 回答