你需要什麼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呢? –