微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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.

原文地址:https://www.jb51.cc/c/117459.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐