c++ - 迭代器失效 - end() 是否算作迭代器?

标签 c++ c++11 iterator multimap

我在使用 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;
}

目的是使用特定键(在本例中为“a”)获取多重映射中的所有现有项目,并在第二个键(“b”)下复制它们。实际上,第一个循环永远不会退出,因为 it 永远不会结束匹配 range.second。处理完映射中的第三个元素后,++it 使迭代器指向新插入的第一个元素。

我已经在 VS2012、Clang 和 GCC 上尝试过,同样的事情似乎在所有编译器中都会发生,所以我认为它是“正确的”。我是不是对“没有迭代器或引用无效”这句话读得太多了? end() 在这种情况下不算作迭代器吗?

最佳答案

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

这里,iEnd 包含一个尾后迭代器。对 multimap::insert 的调用不会使该迭代器无效;它仍然是一个有效的尾后迭代器。因此循环等效于:

for(auto i = iBeg; i != testMap.end(); ++i)

如果你不断添加元素,这当然是一个无限循环。

关于c++ - 迭代器失效 - end() 是否算作迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19393353/

相关文章:

c++ - 如何确保使用移动构造函数

iterator - 在不创建临时向量的情况下迭代成对的 block

c++ - ADT - 迭代器 - 运算符++

c++ - 如何用我自己的实现替换 MS VC++ 项目中的 WinAPI 函数调用(名称和参数集相同)?

C++11 - 如何将 priority_queue 与共享指针 vector 一起使用?

c++ - 错误:成员- “Graph::V”不是类型名称

c++ - 警告 C4477 'wprintf_s' : format string '%s' requires an argument of type 'wchar_t *'

c++ - 如何正确使用vector<uint8_t>.data()?

c++ - 读取/写入同一设备时 Portaudio 挂起

C++ 纯虚函数的多重继承问题