我使用SGI STL(GCC)作为自定义库的参考,而在挖掘std::list::swap()
时遇到了以下实现,
注意:此方法无法正确处理相邻节点。
// namespace std {
// namespace __detail {
void
_List_node_base::swap(_List_node_base& __x, _List_node_base& __y) throw()
{
if ( __x._M_next != &__x )
{
if ( __y._M_next != &__y )
{
// Both __x and __y are not empty.
std::swap(__x._M_next,__y._M_next);
std::swap(__x._M_prev,__y._M_prev);
__x._M_next->_M_prev = __x._M_prev->_M_next = &__x;
__y._M_next->_M_prev = __y._M_prev->_M_next = &__y;
}
else
{
// __x is not empty, __y is empty.
__y._M_next = __x._M_next;
__y._M_prev = __x._M_prev;
__y._M_next->_M_prev = __y._M_prev->_M_next = &__y;
__x._M_next = __x._M_prev = &__x;
}
}
else if ( __y._M_next != &__y )
{
// __x is empty, __y is not empty.
__x._M_next = __y._M_next;
__x._M_prev = __y._M_prev;
__x._M_next->_M_prev = __x._M_prev->_M_next = &__x;
__y._M_next = __y._M_prev = &__y;
}
}
这让我觉得好像可以简化为,
void
_List_node_base::swap(_List_node_base& __x, _List_node_base& __y) throw()
{
_List_node_base* __xnext = __x._M_next;
_List_node_base* __xprev = __x._M_prev;
_List_node_base* __ynext = __y._M_next;
_List_node_base* __yprev = __y._M_prev;
__xnext->_M_prev = __xprev->_M_next = &__y;
__ynext->_M_prev = __yprev->_M_next = &__x;
std::swap(__x._M_next,__y._M_next);
std::swap(__x._M_prev,__y._M_prev);
}
我已针对所有情况(空/空,空/非空等)对此进行了测试,包括引用同一节点的__x
和__y
,并且似乎工作,但是,我对SGI代码库的信任使我怀疑自己。
所以我的问题是:这是正确的吗?如果是这样,使用较长版本会有什么好处吗?
谢谢。
答案 0 :(得分:2)
自我分配检查风靡一时。他们现在被认为是悲观和隐藏的错误。您可能希望找到更现代的灵感来源。