c++ - std::vector::erase(iterator position) 不一定调用相应元素的析构函数

标签 c++ stl

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

V.erase(V.begin() + 2) 删除第三个元素。

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

即删除 vector 中的元素 i 并不能保证调用 ith<​​/em> 析构函数。 对于 std::list,情况并非如此。删除 ith<​​/em> 元素会调用 ith<​​/em> 元素的析构函数。

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 个位置包含原始内存(不是完全构造的对象 T)。因此实现需要调用移动构造函数从第 4 个位置移动到第 3 个位置。

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

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

关于c++ - std::vector::erase(iterator position) 不一定调用相应元素的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17492092/