set::erase()作为参数set::end时的行为如何?
How does set::erase() behave for set::end as its argument?
假设我们有这段代码:
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 fault
或aborted
等信号并获得运行时错误?或者这个特殊情况是在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
'。过端迭代器是不可解引用的,所以你会得到未定义的行为。
是否有可能接收到分割错误或中止等信号并获得运行时错误?
是的,这是可能的,但是你根本不能保证会发生什么。
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何在构造函数参数中初始化"std::set"?
- 函数对象无法识别它获得的参数(std::set<int>)
- 在C++中编写简单的 get/set 方法时,是否应始终使用 const 引用作为参数
- STL中set的insert函数中为什么存在位置参数
- 自定义std::set比较函数的参数
- Std::set构造函数第二个参数错误
- set::erase()作为参数set::end时的行为如何?