list 中 erase 方法删除指定的元素,并且返回下一个元素的地址。
下面的代码演示 erase() 的行为
#include <list>
#include <iostream>
using namespace std;
int list_test2() {
int i;
list<int> ilist = {1, 2, 3, 4, 5};
list<int>::iterator ite = ilist.begin();
cout << "first element = " << *ite << '\n'; // 1
ite++;
cout << "second element = " << *ite << '\n'; // 2
cout << "delete second element\n";
cout << "current element after deletion = " << *(ilist.erase(ite)) << '\n'; // 3
cout << endl;
}
下面的是 erase() 的源代码片段
template <class _Tp, class _Alloc>
typename list<_Tp, _Alloc>::iterator
list<_Tp, _Alloc>::erase(const_iterator __p)
{
#if _LIBCPP_DEBUG_LEVEL >= 2
_LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(&__p) == this,
"list::erase(iterator) called with an iterator not"
" referring to this list");
#endif
_LIBCPP_ASSERT(__p != end(),
"list::erase(iterator) called with a non-dereferenceable iterator");
__node_allocator& __na = base::__node_alloc();
__link_pointer __n = __p.__ptr_; // __n 得到当前要删除的 node 的当前位置
__link_pointer __r = __n->__next_; // __r 指向当前要删除的 node 的下一个节点
base::__unlink_nodes(__n, __n);
--base::__sz();
#if _LIBCPP_DEBUG_LEVEL >= 2
__c_node* __c = __get_db()->__find_c_and_lock(this);
for (__i_node** __ip = __c->end_; __ip != __c->beg_; )
{
--__ip;
iterator* __i = static_cast<iterator*>((*__ip)->__i_);
if (__i->__ptr_ == __n)
{
(*__ip)->__c_ = nullptr;
if (--__c->end_ != __ip)
memmove(__ip, __ip+1, (__c->end_ - __ip)*sizeof(__i_node*));
}
}
__get_db()->unlock();
#endif
__node_pointer __np = __n->__as_node();
__node_alloc_traits::destroy(__na, _VSTD::addressof(__np->__value_));
__node_alloc_traits::deallocate(__na, __np, 1);
#if _LIBCPP_DEBUG_LEVEL >= 2
return iterator(__r, this);
#else
return iterator(__r); // 返回被删除元素的下一个节点的位置
#endif
}