Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

efficient way to insert a unique_ptr into a map without deleting the pointer if the key already exists [duplicate]

Tags:

c++

c++17

The easy way is 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)});

However, this doesn't look too efficient, as I have to find the key in the map twice. One to check if the key doesn't exist, and the insert function will also do the same.

If I simply use mymap.insert({5, std::move(myptr)}); then my unique ptr (myptr) is gone if pair.second returns false (key already exists).

EDIT:

Apparently the answer is on C++17, with try_emplace, and it's already available in the compiler I'm using (vs2015) and since I'm working on a personal project, I can afford to use it.

like image 264
Gam Avatar asked Jun 10 '16 19:06

Gam


2 Answers

If you are not going to store nullptrs in your map then you can do it like this:

auto& r = mymap[5];
if ( r == nullptr )
    r = std::move(myptr);
like image 65
Leon Avatar answered Oct 30 '22 02:10

Leon


The standard trick is to search for the insertion point:

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))
}
like image 35
Joshua Green Avatar answered Oct 30 '22 03:10

Joshua Green