无效迭代器的结果传递给std :: unordered_set :: erase()

问题描述:

std :: unordered_set :: erase()有3个重载:在一个引用中,传递一个“无效”值,即一个不' t存在于该集合中,只是让erase()返回0.但其他两个重载又如何?无效迭代器的结果传递给std :: unordered_set :: erase()

C++ 11标准是否说在这种情况下erase()应该做什么,或者它依赖于编译器?它应该返回end()还是未定义的行为?

我在说明书cppreference.com,cplusplus.com中找不到答案。在IBM网站上,他们说如果操作后没有元素,它会返回end(),但如果操作本身由于无效的迭代器而失败会发生什么?

一般来说,在这种情况下,STL容器的erase()方法是否具有未定义的行为? (所以我需要检查我的迭代器之前,我通过任何擦除(),或使用unordered_set :: erase()重载它需要一个value_type引用,如果失败,它将简单地返回0)

+0

如果你正在处理一个无效的迭代器,你已经在其他地方发生了错误。标准库不关心。为什么要这样?它只允许你访问有效的迭代器 - 你以后做的任何事情都是你的问题。 – Xeo 2013-03-06 13:24:12

这是两个完全不同的情况。没有“无效值”,集合中不存在的值仍然有效。所以你传递一个不包含在该集合中的有效值,从而返回0 - 没有元素被擦除。

其他重载是完全不同的。该标准要求传递给擦除方法的迭代器分别是“有效和无法引用”和“有效的迭代器范围”。否则,行为是不确定的。

所以是的,迭代器必须是有效的。但是你不能检查一个迭代器是否以编程方式有效 - 你必须从你的程序逻辑确定它们是。

有一个尝试删除集合中不存在的值并尝试从无效的迭代器中删除之间存在很大的语义差异。

试图使用无效的迭代器是未定义的行为,并会严重结束。

你有没有具体的用例,你想知道什么时候你想擦除一个无效的迭代器?

+0

不,但我想知道会发生什么。有没有定义的行为,例如“没有任何变化”,例如“删除使用无效的迭代器”或“删除使用有效的迭代器指向另一个容器中的值”? – cfa45ca55111016ee9269f0a52e771 2013-03-06 13:27:39

+0

我想知道会发生什么,以便我的代码可以使用assert()来捕获无效的检测结果。 – cfa45ca55111016ee9269f0a52e771 2013-03-06 13:29:05

+2

不可以。像111111的答案所述,无效的迭代器传递给'erase'会导致未定义的行为。 – us2012 2013-03-06 13:29:31