2016-06-10 36 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)) 
}