我使用 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 代码库的信任让我怀疑自己。
所以我的问题是:这是正确的吗?如果是的话,使用更长的版本有什么好处吗?
谢谢。
最佳答案
self 分配检查风靡一时。众所周知,他们现在是悲观主义者和隐藏错误的人。您可能想找到更现代的灵感来源。
关于c++ - gcc 列表节点交换实现过于复杂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30830988/