set::erase()作为参数set::end时的行为如何?

How does set::erase() behave for set::end as its argument?

本文关键字:set 参数 erase end      更新时间:2023-10-16

假设我们有这段代码:

set<int> s;
set<int>::iterator it = s.find(val);
s.erase(it);

如cplusplus.com所说,如果set<int> s中不存在int val,那么s.find(val)将返回set::end

现在我的问题是,如果我们将set::end传递给set::erase(),会发生什么?

是否有可能接收segmentation faultaborted等信号并获得运行时错误?或者这个特殊情况是在set中处理的?

在c++ 03中,表69定义了接受单个迭代器的std::set::erase()的行为,其中有以下假设(添加了高亮):

69年表,X是一个关联容器类,一个是X的值,a_uniq是X的值,当X支持独特的钥匙,和a_eq X的值,当X支持多个键,i和j满足value_type输入迭代器要求和参考元素,(i, j)是一个有效范围,p是一个有效的迭代器, q是一个有效的解除迭代器到, (q1、q2)是一个有效范围,t是一个X的值::value_type,k是X::key_type类型的值,c是X::key_compare类型的值。

表69是这样描述erase()函数的:

a.erase(q) -删除q指向的元素

也就是说,迭代器必须是可解引用的。如果不是,则为未定义行为,因为没有满足前置条件。

对于库的行为没有给出任何特定的承诺。一些库(比如MSVC的库)可以在某些配置中包含迭代器调试。例如,当在VS 2012中运行调试配置时,你会看到以下内容:

---------------------------
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: C:Windowssystem32MSVCP110D.dll
File: c:program files (x86)microsoft visual studio 11.0vcincludextree
Line: 1326
Expression: map/set erase iterator outside range
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort   Retry   Ignore   
---------------------------

这是未定义的行为。也就是说,它可能什么都不做,使程序崩溃等等。不要这样做,即使你的stdlib实现"工作得很好"。

对于关联容器,erase的定义如下:

a.erase(q)
返回类型:iterator
擦除q所指向的元素。返回一个迭代器,该迭代器指向紧接在q之后的元素,而不是被擦除的元素。如果不存在这样的元素,则返回a.end()

此函数仅根据q定义。q被描述为"有效的可解引用"const迭代器为a '。过端迭代器是不可解引用的,所以你会得到未定义的行为。

是否有可能接收到分割错误或中止等信号并获得运行时错误?

是的,这是可能的,但是你根本不能保证会发生什么。