对于诸如std::map< std::string, std::unique_ptr< Foo >>
之类的容器,从gcc 4.7.2开始,它似乎尚未在stdc ++中实现{<1}}。
不幸的是,我无法直接按值存储Foo,因为它是一个抽象的超类。
作为一个简单但效率低下的占位符,我刚刚将emplace()
与std::map< std::string, Foo* >
一起用于垃圾收集。
一旦emplace()可用,您是否有更高效且更容易替换的临时解决方案?
答案 0 :(得分: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;
}
事实上, you should not use emplace
with 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;
}
答案 1 :(得分:2)
作为一种解决方法,您可以使用boost
容器,即使在C ++ 03编译器下也支持大多数C ++ 11功能,并且具有与std
容器相同的布局,然后当您拥有该功能时std
1}}你可以切换名称空间!