简体   繁体   English

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

[英]Replace existing and add new entries in std::map

Consider following snippet: 考虑以下代码段:

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;
}

I assume using the returned iterator from insert is the most efficient version. 我假定使用从insert返回的迭代器是最有效的版本。

However at first, I did just thought assigning the iterators only works fine (note I am not dereferencing the iterator anymore here). 但是起初,我确实以为分配迭代器只能正常工作(请注意,我不再在这里不再引用迭代器了)。

1.) 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;

I know its obsolete as I already matched the key and only care about the value. 我知道它已经过时了,因为我已经匹配了密钥并且只关心值。 This error occurs only because of the key being a const std::string If I am not completely out of my mind :D 仅由于键为const std :: string才会发生此错误,如果我不是完全不注意:D

2.) 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;

This is the thing I actually don't understand. 这是我实际上不了解的东西。 How is the assignment of an iterator in a std::map supposed to behave? std :: map中的迭代器分配应该如何表现? Although I do program C++ for a few years already, I never encountered a scenario where I did so for any container. 尽管我已经从事C ++编程工作了几年,但我从未遇到过对任何容器都进行过这种编程的情况。 I have not found a lot of information about assigning iterators in general during a bit of research. 在一些研究中,我通常没有找到有关分配迭代器的大量信息。

And finally would there be an even more elegant way of doing what I want to achieve (using C++11 features, maybe C++14)? 最后,是否会有一种更优雅的方式来实现我想要的目标(使用C ++ 11功能,也许是C ++ 14)?

Why make it so complicated? 为什么要这么复杂? Why not simply 为什么不简单

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

If they key exists, the data will be changed. 如果它们存在,则数据将被更改。 If the key doesn't exist, then the pair will be inserted. 如果密钥不存在,则将插入该对。


Also don't forget that the value_type of std::map (and std::unordered_map for that matter) is std::pair<const Key, T> . 同样不要忘记std::mapvalue_type (和std::unordered_map )是std::pair<const Key, T>

As the key is constant you can't simply assign or copy iterators, you can only assign or copy the value. 由于键是常量,因此您不能简单地分配或复制迭代器,而只能分配或复制值。

To answer the first question 回答第一个问题

How is the assignment of an iterator in a std::map supposed to behave? std :: map中的迭代器分配应该如何表现?

:

MapT::Iterator satisfies BidirectionalIterator , which satisfies ForwardIterator , which satisfies Iterator . MapT::Iterator满足BidirectionalIterator ,后者满足ForwardIteratorForwardIterator满足Iterator

An Iterator is CopyAssignable . IteratorCopyAssignable

So the assignment t = v; 因此,分配t = v; will make 将使

  • The value of t is equivalent to the value of v . t的值等于v的值。
  • The value of v is unchanged. v的值不变。

In this case substitute t with pair.first , and v with itSecond . 在这种情况下,将t替换为pair.first ,并将v替换为itSecond Note that the map is not changed with this. 请注意,此地图不会更改。

(imagine pointers. Of course assigning pointers won't modify contents they point to) (想象中的指针。分配指针当然不会修改它们指向的内容)

Assuming C++17 is okay, you can use merge: https://en.cppreference.com/w/cpp/container/map/merge 假设C ++ 17可以,您可以使用合并: https : //en.cppreference.com/w/cpp/container/map/merge

But it doesn't overwrite the data, so you'd have to merge the first into the second. 但是它不会覆盖数据,因此您必须将第一个合并到第二个中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM