迭代器失效 - end()是否计为迭代器?

Jon*_*ter 5 c++ iterator multimap c++11

我使用std::multimap::equal_range()和遇到了以下问题insert().

根据cplusplus.comcppreference.com,std::multimap::insert不会使任何迭代器无效,但以下代码会导致无限循环:

#include <iostream>
#include <map>
#include <string>

int main(int argc, char* argv[])
{
    std::multimap<std::string,int> testMap;
    testMap.insert(std::pair<std::string,int>("a", 1));
    testMap.insert(std::pair<std::string,int>("a", 2));
    testMap.insert(std::pair<std::string,int>("a", 3));

    auto range = testMap.equal_range(std::string("a"));
    for (auto it = range.first; it != range.second; ++it)
    {
        testMap.insert(std::pair<std::string,int>("b", it->second));
        // this loop becomes infinite
    }

    // never gets here
    for (auto it = testMap.begin(); it != testMap.end(); ++it)
    {
        std::cout << it->first << " - " << it->second << std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

目的是使用特定键(在这种情况下为"a")获取多图中的所有现有项,并在第二个键("b")下复制它们.在实践中,会发生的是第一个循环永远不会退出,因为it永远不会最终匹配range.second.处理完映射中的第三个元素后,++it使迭代器指向第一个新插入的项.

我已经尝试过VS2012,Clang和GCC,所有编译器似乎都会发生同样的事情,所以我认为它是"正确的".我是否在"没有迭代器或引用无效"的声明中读得太多了.难道end()不算在这种情况下一个迭代器?

dyp*_*dyp 5

multimap::equal_range返回一个pair第二个元素,在这种情况下是过去元素的迭代器("这是容器的过去的结束值"[container.requirements.general]/6).

我会稍微改写代码来指出一些事情:

auto iBeg = testMap.begin();
auto iEnd = testMap.end();

for(auto i = iBeg; i != iEnd; ++i)
{
    testMap.insert( std::make_pair("b", i->second) );
}
Run Code Online (Sandbox Code Playgroud)

这里iEnd包含一个过去的迭代器.调用multimap::insert不会使此迭代器失效; 它仍然是一个有效的过去的迭代器.因此循环等效于:

for(auto i = iBeg; i != testMap.end(); ++i)
Run Code Online (Sandbox Code Playgroud)

如果你继续添加元素,这当然是一个无限循环.

  • 由于这个,芝诺在他的坟墓中翻身. (2认同)