c – std :: vector :: erase(迭代器位置)不一定会调用相应元素的析构函数

假设我有一个5个元素的std :: vector V,

V.erase(V.begin()2)删除第3个元素.

STL向量实现将向上移动第4和第5个元素,然后破坏第5个元素.

即向量中的擦除元素i不保证调用第i个析构函数.
对于std :: list,情况并非如此.擦除ith元素调用ith元素的析构函数.

STL对这种行为有什么看法?

这是从我的系统的stl_vector.h获取代码

392   iterator erase(iterator __position) {
393     if (__position + 1 != end())
394       copy(__position + 1,_M_finish,__position);
395     --_M_finish;
396     destroy(_M_finish);
397     return __position;

解决方法

C 11标准23.3.6.5/4说(重点是我的):

Complexity: The destructor of T is called the number of times equal to the number of the elements erased,but the move assignment operator of T is called the number of times equal to the number of elements in the vector after the erased elements.

如果实现在第3个元素上调用了析构函数,则它将不符合.

实际上,假设在第3个元素上调用析构函数.由于只擦除了一个元素,因此无法再次调用析构函数.

在析构函数调用之后,第3个位置包含原始内存(不是完全构造的对象T).因此,实现需要调用移动构造函数从第4个位置移动到第3个位置.

它不能破坏第4个元素(因为它不能再调用析构函数),然后从第5个元素移动到第4个元素,它必须调用移动赋值运算符.

此时,实现仍需要将向量大小减小1并销毁第5个元素,但正如我们所见,不允许其他destrucor调用. (另请注意,移动分配运算符不会按标准要求调用两次.)QED.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...