你需要什么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对于使用可用代码很好的答案。避免在用户代码中使用'new'是一个勇敢的原因。然而,假设我没有构建Bar的新实例,而是因为我不知道我有什么样的'Foo',所以我需要在映射中插入'foo-> clone()'。你将如何使'Foo * Bar :: clone()'避免调用'new'?或者这是好的,因为它不会被视为客户端代码? – kfmfe04
巧合的是我今天刚刚处理过。取而代之,让你的克隆函数返回'std :: unique_ptr'。 –
GManNickG
我知道这有点旧,但如果foo-> clone()的用户想要一个shared_ptr呢? –