SGI slist和C ++ 11 forward_list有什么区别?

时间:2011-07-30 19:14:50

标签: list c++11 containers singly-linked-list

除非我遗漏了某些内容,否则SGI slist和C ++ 11 std::forward_list看起来都与我完全相同;两者都实现了单链表。

我认为存在差异,因为C ++标准委员会没有采用名称slist而是选择了一个新名称forward_list,当他们将容器添加到C ++ 0x的标准库中时。

3 个答案:

答案 0 :(得分:14)

一个主要区别是std::forward_list缺少size()成员函数,而sgi::slist则没有。其动机是O(N)size()存在问题。 N2543详细介绍了forward_list的设计决策。

<强>更新

我最近有一个很好的借口来仔细研究这个问题。 slist还有其他成员函数,人们会想到它们是O(1),但实际上是O(N)。其中包括:

iterator previous(iterator pos);
const_iterator previous(const_iterator pos) const;
iterator insert(iterator pos, const value_type& x);
iterator erase(iterator pos);
void splice(iterator position, slist& x);
void splice(iterator position, slist& x, iterator i);

简而言之,如果您不是非常小心,那么使用slist可能会导致严重的性能问题。使用std::forward_list代替确保您可以从单个链接列表中获得预期的O(1)性能。

答案 1 :(得分:3)

简而言之,sgi :: slist和forward_list非常相似。

不同之处在于forward_list缺少一个size()成员函数,该函数包含在sgi :: slist中,forward_list包含一个emplace_after成员函数,该函数不包含在sgi :: slist中。另外,forward_list不提供像sgi :: slist那样的插入和擦除成员函数。

如果您知道其他任何差异,请随时提及。

答案 2 :(得分:1)

我最近遇到了另一个不同之处。方法splice_after具有不同的界面和不同的行为。

1)forward_list要求你传递你作为第二个参数移动的容器:

void splice_after( const_iterator pos, forward_list& other,
                   const_iterator first, const_iterator last );

SLIST:

void splice_after(iterator pos, iterator before_first, iterator before_last)

这与重载类似。

2)特定于上面提到的重载:最后一个迭代器的解释方式不同!在slist移动​​范围[before_first + 1,before_last + 1&gt;]的情况下,forward_list移动​​范围&lt;第一个,最后一个&gt;。因此,在转换代码时(例如,因为在GCC中不推荐使用slist),请确保使用:last = before_last + 1.