【发布时间】:2022-03-17 18:18:25
【问题描述】:
我有一个对象映射,我想更新映射到键的对象,或者创建一个新对象并插入到映射中。更新由一个不同的函数完成,该函数接受一个指向对象的指针 (void update(MyClass *obj))
在地图中“插入或更新”元素的最佳方式是什么?
【问题讨论】:
我有一个对象映射,我想更新映射到键的对象,或者创建一个新对象并插入到映射中。更新由一个不同的函数完成,该函数接受一个指向对象的指针 (void update(MyClass *obj))
在地图中“插入或更新”元素的最佳方式是什么?
【问题讨论】:
【讨论】:
MyClass 对象,然后更新它。如果需要插入非默认对象,或者不更新插入的值,Charles 的方案可能会更好。
update(my_map[key])?这也意味着你总是update(从问题中不清楚)。
使用类似于以下 sn-p 的内容:
std::map<Key, Value>::iterator i = amap.find(key);
if (i == amap.end())
amap.insert(std::make_pair(key, CreateFunction()));
else
UpdateFunction(&(i->second));
如果您想测量可能会提高性能的东西,您可能需要使用 .lower_bound() 来查找条目的位置,并在需要插入新对象的情况下将其用作插入提示。
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));
【讨论】:
i 不等于 amap.begin(),您实际上需要减少它。因此,一个明显的问题是:如何暗示它应该被插入到第一个位置?我想它适用于无提示版本:/
类似:
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);
这里有一个很好的参考link
【讨论】:
MyClass& obj = mymap[2]; update(&obj);
operator[] 已经可以满足您的需求。详情请见the reference。
【讨论】:
insert 的返回值是“一对由插入元素(或阻止插入的元素)的迭代器和表示插入是否发生的布尔值组成。”
因此你可以简单地做
auto result = values.insert({ key, CreateFunction()});
if (!result.second)
UpdateFunction(&(result.first->second));
注意: 由于您的问题涉及原始指针,并且您说您希望 Update 函数获取指针,因此我在我的 sn-p.xml 中做出了这个假设。假设 CreateFunction() 返回一个指针,而 UpdateFunction() 需要一个指针。
我强烈建议不要使用原始指针。
【讨论】:
在 C++17 中,函数 insert_or_assign 如果不存在则插入,如果存在则更新。
【讨论】: