将项目"更新插入"到映射<键、shared_ptr的正确方法<foo>>

Correct way of 'upserting' items into map<key, shared_ptr<foo>>

本文关键字:lt gt ptr foo 方法 插入 更新 项目 映射 shared      更新时间:2023-10-16

我想将项目更新(更新或插入)到map<int,shared_ptr<PortfolioEntry>>结构中。我当前的代码如下所示:

auto existing = positions.find(id);
if (existing == positions.end())
{
  positions[id] = make_shared<PortfolioEntry>(id, amount, price);
}
else
{
  // update positions[id]
}

所以我想知道这是否是正确的做事方式。find()效率高吗?分配给positions[id]是正确的方法,还是我应该使用一些std::move构造?

最快的方法是尝试先插入,如果未插入任何内容,则更改迭代器值:

  template < class KeyType, class ElementType >
  bool SetAndCheckChanged(
    std::map< KeyType, ElementType >& the_map,
    KeyType const& key,
    ElementType const& new_value)
  {
    typedef typename std::map< KeyType, ElementType >::iterator Iterator;
    typedef typename std::pair< Iterator, bool > Result;
    Result result = the_map.insert(typename std::map< KeyType, ElementType >::value_type(key, new_value));
    if (!result.second)
    {
      if ( !(result.first->second == new_value ))
      {
        result.first->second = new_value;
        return true;
      }
      else
        return false; // it was the same
    }
    else
      return true;  // changed cause not existing
  }

然后(使用 c++11),您可以将元素放置在映射中而不是使用 operator[]

positions.emplace(id, make_shared<PortfolioEntry>(id,amount,price));

如何处理更新取决于 PortfolioEntry 类。如果它只包含id,数量和价格,并且构造很便宜,你可以简单地覆盖它,并完全删除更新案例。如果它更复杂,您无论如何都必须执行更新代码。

对于更新插入,您可以使用下一行:

positions[id] = make_shared<PortfolioEntry>(id, amount, price);

如果它已经存在 - 它将被替换为新值,如果不存在 - 它将入。您无需调用查找。上面的 1 行将完成这项工作。