Search code examples
c++dictionarystlshared-ptr

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


I want to upsert (update or insert) items into a map<int,shared_ptr<PortfolioEntry>> structure. My current code is something like the following:

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

So I'm wondering if it's the right way of doing things. Is find() efficient? Is assigning to positions[id] the right way to do this, or should I use some std::move construct?


Solution

  • The fastest way is to try to insert first and change the iterator value if nothing was inserted:

      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
      }