简体   繁体   English

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

[英]Result of invalid iterator passed to std::unordered_set::erase()

std::unordered_set::erase() has 3 overloads: In the one taking a reference, passing an "invalid" value, ie one that doesn't exist in the set, simply makes erase() return 0. But what about the other two overloads? std :: unordered_set :: erase()有3个重载:在一个引用中,传递一个“无效”值,即,该值不存在的值,仅使delete()返回0。其他两个超载?

Does the C++11 standard say what erase() should do in this case, or it's compiler dependent? 在这种情况下,C ++ 11标准是否规定了delete()应该做什么,还是取决于编译器? Is it supposed to return end() or undefined behavior? 它应该返回end()还是未定义的行为?

I couldn't find an answer in the specification, cppreference.com, cplusplus.com. 我在规范cppreference.com,cplusplus.com中找不到答案。 On IBM site they say it returns end() if no element remains after the operation, but what happens if the operation itself fails due to an invalid iterator? 在IBM网站上,他们说如果操作后没有剩余元素,它将返回end(),但是如果操作本身由于无效的迭代器而失败,该怎么办?

And in general, do erase() methods for STL containers simply have undefined behavior in these case? 通常,在这种情况下,用于STL容器的delete()方法是否只是具有未定义的行为? (so I need to check my iterators before I pass any to erase(), or use the unordered_set::erase() overload which takes a value_type reference, which would simply return 0 if it fails) (因此,我需要在将任何迭代器传递给delete()之前检查我的迭代器,或者使用unordered_set :: erase()重载,该重载使用value_type引用,如果失败,则将简单地返回0)

There is a big semantic difference between trying to remove a value that doesn't occur in set and trying to erase from a invalid iterator. 尝试删除set中未出现的值与尝试从无效的迭代器中删除之间存在很大的语义差异。

Trying to use an invalid iterator is undefined behaviour and will end badly. 尝试使用无效的迭代器是未定义的行为,并且将严重失败。

Do you have a specific use-case you are thinking of when you might want to erase an invalid iterator? 您是否在考虑何时要删除无效的迭代器的特定用例?

These are two completely different cases. 这是两种完全不同的情况。 There is no "invalid value", values that don't exist in the set are still valid. 没有“无效值”,集合中不存在的值仍然有效。 So you pass a valid value that s not contained in the set and thus get 0 returned - no elements have been erased. 因此,您传递的有效值未包含在集合中,因此返回0-没有擦除任何元素。

The other overloads are completely different. 其他过载完全不同。 The standard requires the iterators passed to the erase methods to be "valid and dereferencable" and "a valid iterator range", respectively. 该标准要求传递给擦除方法的迭代器分别是“有效且可取消引用的”和“有效迭代器范围”。 Otherwise the behavior is undefined. 否则,行为是不确定的。

So yes, iterators have to be valid. 所以是的,迭代器必须有效。 But you cannot check if an iterator is valid programmatically - you have to make sure from your program logic, that they are. 但是您不能检查迭代器在程序上是否有效-您必须从程序逻辑中确保它们是有效的。

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

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