2

当我有一个 std::map 时,是否有一种优雅的方式可以同时:

  1. 插入/编辑给定键的元素
  2. 获取插入元素的迭代器

我发现防止在地图中进行 2 次查找的最佳方法是:

std::map<int, int> myMap;
//do some stuff with the map
std::map<int,int>::iterator  it = myMap.insert(std::pair<int, int>(0,0)).first;
it->second = 0; //necessary because insert does not overwrite the values

是否可以在单个语句/行中同时完成这两件事?谢谢

4

4 回答 4

4

唉,STL 函数和容器并不总是如您所愿。这是两个通用版本,第一个更像您上面的代码:

template<class Map>
inline typename Map::iterator ForceInsert1( 
    Map&                           m, 
    const typename Map::key_type&  k, 
    const typename Map::data_type& d )
{
    typename Map::iterator it = m.insert( 
        typename Map::value_type( k, d ) ).first;
    it->second = d; // only necessary if the key already exists
    return it;
}

template<class Map>
inline typename Map::iterator ForceInsert2( 
    Map&                           m, 
    const typename Map::key_type&  k, 
    const typename Map::data_type& d )
{
    typename Map::iterator it = m.find( k );
    if( it != m.end() )
    {
        it->second = d;
    }
    else
    {
        it = m.insert( typename Map::value_type( k, d ) ).first;
    }
    return it;
}

typedef std::map<int, int> MyMap;
void Foo( MyMap& myMap )
{
    ForceInsert1( myMap, 42, 100 );
    ForceInsert2( myMap, 64, 128 );
}
于 2012-04-13T20:40:40.117 回答
1

你可以这样做:

map<int, int> m;
map<int, int>::iterator iter;
(iter = (m.insert(make_pair(1,1))).first)->second = 5;

显然,第二个值make_pair是无关紧要的(只要它是正确的类型)。在这里,您将迭代器指向的值设置为 5。

有点厚脸皮,从技术上讲,这也是一种说法:

iter = myMap.insert(make_pair(0,0)).first, iter->second = 0;

逗号 ( ,) 运算符保证所有副作用发生在评估 rhs 之前,因此iter具有正确的值

于 2012-04-13T20:33:42.860 回答
1

如果您只想要该值而不是该对:

int& value = myMap[0] = 0;
于 2012-04-13T21:22:45.417 回答
0
myMap[0] = 0;

如果不存在,此行将插入一个键为 0 的值,并且在任何一种情况下,它都会将该键的值设置为 0。

这与您所拥有的大致相似,可以将其制成一行:

myMap.insert(std::make_pair(0,0)).first->second = 0;
于 2012-04-13T20:20:12.683 回答