开发者

STL map - insert or update

开发者 https://www.devze.com 2022-12-29 05:43 出处:网络
I have a map of objects and I want to update the object mapped to a key, or create a new object and insert into the map. The 开发者_高级运维update is done by a different function that takes a pointer

I have a map of objects and I want to update the object mapped to a key, or create a new object and insert into the map. The 开发者_高级运维update is done by a different function that takes a pointer to the object (void update(MyClass *obj))

What is the best way to "insert or update" an element in a map?


The operator[]    


With something like the following snippet:

std::map<Key, Value>::iterator i = amap.find(key);

if (i == amap.end())
    amap.insert(std::make_pair(key, CreateFunction()));
else
    UpdateFunction(&(i->second));

If you want to measure something that might improve performance you might want to use .lower_bound() to find where an entry and use that as a hint to insert in the case where you need to insert a new object.

std::map<Key, Value>::iterator i = amap.lower_bound(key);

if (i == amap.end() || i->first != key)
    amap.insert(i, std::make_pair(key, CreateFunction()));
                                       // Might need to check and decrement i.
                                       // Only guaranteed to be amortized constant
                                       // time if insertion is immediately after
                                       // the hint position.
else
    UpdateFunction(&(i->second));


something like:

map<int,MyClass*> mymap;
map<int,MyClass*>::iterator it;

MyClass* dummy = new MyClass();
mymap.insert(pair<int,MyClass*>(2,dummy));

it = mymap.find(2);
update(it.second);

here a nice reference link


The operator[] already does, what you want. See the reference for details.


The return value of insert is "a pair consisting of an iterator to the inserted element (or to the element that prevented the insertion) and a bool denoting whether the insertion took place."

Therefore you can simply do

auto result = values.insert({ key, CreateFunction()});
if (!result.second)
    UpdateFunction(&(result.first->second));

NOTE: Since your question involved raw pointers, and you said you wanted your Update function to take a pointer, I have made that assumption in my snippet. Assume that CreateFunction() returns a pointer and UpdateFunction() expects a pointer.

I'd strongly advise against using raw pointers though.


In C++17, function insert_or_assign insert if not existing and update if there.

0

精彩评论

暂无评论...
验证码 换一张
取 消