2016-06-10 50 views
9

簡單的方法是obviosuly有效的方式

std::map<int,std::unique_ptr<something>> mymap; 

auto f = mymap.find(5); 
std::unique_ptr<something> myptr; 

if (f == mymap.end()) 
    mymap.insert({5, std::move(myptr)}); 

然而,這並不顯得太有效,因爲我必須找到問題的關鍵在地圖上兩次。一個用來檢查密鑰是否不存在,而插入功能也會這樣做。

如果我只是使用mymap.insert({5, std::move(myptr)});,那麼如果pair.second返回false(鍵已經存在),那麼我的唯一ptr(myptr)就會消失。

編輯:

顯然,答案是C++ 17,與try_emplace,並且它已經可以在我使用(vs2015)編譯器和因爲我工作的一個個人項目,我可以負擔得起使用它。

+1

你爲什麼說這看起來並不高效?對我來說看起來很好。 –

+0

如果你擔心'std :: map :: find'的複雜性,那麼你可能使用了錯誤的容器? 'std :: unordered_map'位於散列表的頂部,使一些操作O(1)分期付款而不是O(日誌n) - 查找包含。 – Conduit

+6

看起來像你想要在下一個標準['try_emplace'](http://en.cppreference.com/w/cpp/container/map/try_emplace)即將到來 – NathanOliver

回答

5

如果你不打算存儲nullptr在你的地圖,那麼你可以做這樣的:

auto& r = mymap[5]; 
if (r == nullptr) 
    r = std::move(myptr); 
+1

這是一個非常有趣的想法! – James

0

也許我不太瞭解情況,但爲什麼移動任何東西,而不是佈設了嗎?

std::map<int,std::unique_ptr<something>> mymap; 

auto f = mymap.find(5); 

if (f == mymap.end()) 
    mymap.emplace(5, std::make_unique<something>(myptr)); 
+1

這仍然執行兩次查找,就像原始的OP代碼段一樣。 –

2

標準的訣竅是尋找插入點:

auto f = mymap.lower_bound(5); 
if ((f == mymap.end()) || mymap.key_comp()(5, f->first)) { 
    mymap.insert(f, {5, std::move(myptr)}); // or mymap.emplace_hint(f, 5, std::move(myptr)) 
}