SGI slist 和 C++11 forward_list 有啥区别?

Posted

技术标签:

【中文标题】SGI slist 和 C++11 forward_list 有啥区别?【英文标题】:What is the difference between SGI slist and C++11 forward_list?SGI slist 和 C++11 forward_list 有什么区别? 【发布时间】:2011-10-16 15:48:51 【问题描述】:

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

我认为这是有区别的,因为 C++ 标准委员会在将容器添加到 C++0x 标准库时并没有采用名称 slist,而是选择了一个新名称 forward_list。

【问题讨论】:

主要区别在于 forward_list 对象是单链表,因此它们只能向前迭代,以换取更小更高效。 std::list 是双向链表 【参考方案1】:

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

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

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

列表:

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

这与重载类似。

2) 特定于上面提到的重载:最后一个迭代器的解释不同!其中 slist 移动范围 [ before_first + 1, before_last + 1 >,forward_list 移动范围 。因此,在转换代码时(例如,由于 slist 在 GCC 中已弃用),请务必使用:last = before_last + 1。

【讨论】:

【参考方案2】:

一个主要区别是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) 性能。

【讨论】:

感谢您的回复。读那篇论文很有趣。我同意不包含 size() 成员函数的决定。我想如果我必须知道我可以使用 std::list 的大小。【参考方案3】:

简单来说,sgi::slist 和 forward_list 非常相似。

区别在于 forward_list 缺少一个 size() 成员函数,它包含在 sgi::slist 中,而 forward_list 包含一个 emplace_after 成员函数,它不包含在 sgi::slist 中。此外,forward_list 不像 sgi::slist 那样提供插入和擦除成员函数。

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

【讨论】:

以上是关于SGI slist 和 C++11 forward_list 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

SGI-STL简记-迭代器解析

C++11的右值引用移动语义(std::move)和完美转发(std::forward)详解

链表之SLIST

链表之SLIST

链表之SLIST

C++11:移动语义Move Semantics和完美转发Perfect Forwarding