问题描述
我正在编写一个使用 std::map::erase
的简单程序。
程序很好,但有一点我不明白。
如果我将第一个迭代器超出第二个迭代器的间隔传递给 erase
函数,则该函数不会擦除任何内容。而且还不错。
另一方面,如果我将 std::distance
与第二个迭代器之后的第一个迭代器一起使用,则此函数“失败”。我知道这是由于地图迭代器的性质造成的,例如 std::vector
没有这个问题。
但我不明白 map::erase
如何知道间隔是否有效。
解决方法
来自std::distance
's specification:
如果最后一个不能从第一个通过 (可能重复)先递增。
C++11 之后的随机访问迭代器有一个无关紧要的例外,但这不适用于地图。这是未定义的行为,因此您可能会遇到“失败”,甚至崩溃。
std::map
的 erase()
方法似乎也表明 this is undefined behavior,too:
- 移除[first;]范围内的元素最后),这必须是一个 *this 中的有效范围。
您传递的迭代器值不包含“有效范围”,因此这也是未定义的行为。尽管今天这似乎什么也没做,但如果下周您的代码开始崩溃,那么生成的代码完全在其权利范围内,因为这就是“未定义行为”的含义。
总而言之,在这种情况下,erase()
和 std::distance
都会导致未定义的行为。
没有!
它只是假设范围是有效的,如果它没有引起一些意外的症状,你只会注意到它不是。
是否发生完全取决于内部实现的细节,而且很可能是偶然的。这是教科书未定义的行为。