替换现有的并在std :: map中添加新条目

时间:2018-06-28 09:24:19

标签: c++ stl iterator stdmap

考虑以下代码段:

MapT map;

map["A"] = 1;
map["B"] = 2;
map["C"] = 3;
map["D"] = 4;
map["E"] = 5;

MapT mapSecond;

mapSecond["A"] = 10;
mapSecond["B"] = 20;
mapSecond["C"] = 30;
mapSecond["X"] = 4;
mapSecond["Y"] = 5;

MapT::const_iterator itSecond = mapSecond.begin();
MapT::iterator it = map.begin();

for (; itSecond != mapSecond.end(); ++itSecond)
{
    std::pair<MapT::iterator, bool> pair = map.insert(std::make_pair(itSecond->first, itSecond->second));
    if (!pair.second)
    {
        pair.first->second = itSecond->second;
    }
}

for (; it != map.end(); ++it)
{
    std::cout << it->first << " " << it->second << std::endl;
}

我认为使用insert中返回的迭代器是最有效的版本。

但是,起初我只是以为分配迭代器就可以了(请注意,我不再在这里不再引用迭代器了。)

1。)

// assigning the dereferenced iterator (i.e.: the underlying std::pair)
// resulting in no match for binary '=' operator for const std::string
*pair->first = *itsecond;

我知道它已经过时了,因为我已经匹配了键并且只关心值。仅由于键为const std :: string才会发生此错误,如果我不是完全不在意:D

2。)

// assigning the iterator itself
// does not compile as long as itSecond is of type const_iterator ?
// does nothing in case itSecond is of type iterator
pair.first = itSecond;

这是我实际上不了解的东西。 std :: map中的迭代器分配应该如何表现? 尽管我已经从事C ++编程工作了几年,但我从未遇到过对任何容器都进行过这种编程的情况。在一些研究中,我没有找到关于分配迭代器的大量信息。

最后是否会有一种更优雅的方式来实现我想要的目标(使用C ++ 11功能,也许是C ++ 14)?

3 个答案:

答案 0 :(得分:2)

为什么要这么复杂?为什么不简单

map[itSecond->first] = itSecond->second;

如果它们存在键,则数据将被更改。如果密钥不存在,则将插入该对。


也不要忘记std::map中的value_type(以及std::unordered_map)是std::pair<const Key, T>

由于键是恒定,因此您不能简单地分配或复制迭代器,而只能分配或复制值。

答案 1 :(得分:1)

回答第一个问题

  

在std :: map中分配迭代器应该如何表现?

MapT::Iterator满足BidirectionalIterator,满足ForwardIterator,满足Iterator

IteratorCopyAssignable

因此,任务t = v;将完成

  
      
  • t的值等于v的值。
  •   
  • v的值不变。
  •   

在这种情况下,将t替换为pair.first,将v替换为itSecond。请注意,此地图不会更改。

(想象中的指针。分配指针当然不会修改它们指向的内容)

答案 2 :(得分:0)

假设C ++ 17可以,您可以使用merge:https://en.cppreference.com/w/cpp/container/map/merge

但是它不会覆盖数据,因此您必须将第一个合并到第二个。