【发布时间】:2010-11-09 21:48:20
【问题描述】:
谁能解释一下为什么没有为 std::list 实现 operator[] ?我搜索了一下,但没有找到答案。实施起来不会太难还是我错过了什么?
【问题讨论】:
谁能解释一下为什么没有为 std::list 实现 operator[] ?我搜索了一下,但没有找到答案。实施起来不会太难还是我错过了什么?
【问题讨论】:
实际上,绝对没有理由不提供 operator[] 或至少方法 at(int),原因有两个:
【讨论】:
std::list<T>::operator[] 的自定义实现是有效的? (顺便说一句,根据 Stroustrup 的说法,您应该使用的标准容器是 std::vector)。
我想我在另一篇 SO 帖子 Extending std::list 中找到了答案
“你的 operator[] 是 O(N) 时间” - 这个 正是为什么它不包含在 标准的 std::list。 – 迈克尔 伯尔 12 月 14 日 17:29
不过,这是唯一的原因吗?
编辑:尽管正如人们所提到的,这似乎更多的是关于性能的一致性问题,而不是严格的性能问题。
【讨论】:
LinkedList 没有提供索引器,原因大致相同——它太具有欺骗性了。传统上,当某物具有位置索引器时,假定操作是 O(1)。
按索引检索元素是链表的 O(n) 操作,std::list 就是这样。因此决定提供operator[] 具有欺骗性,因为人们会很想主动使用它,然后您会看到如下代码:
std::list<int> xs;
for (int i = 0; i < xs.size(); ++i) {
int x = xs[i];
...
}
这是 O(n^2) - 非常讨厌。所以 ISO C++ 标准特别提到所有支持operator[] 的 STL 序列都应该在摊销的常数时间内完成(23.1.1[lib.sequence.reqmts]/12),这对于vector 和deque 是可以实现的,但是不是list。
对于你真正需要这种东西的情况,你可以使用std::advance算法:
int iter = xs.begin();
std::advance(iter, i);
int x = *iter;
【讨论】:
std::next 是更合适的函数 (std::list< int > list; ...; *std::next(std::begin(list), index) = 1;),因为 it leaves its argument unmodified。
这不会太难(对于实施者),但在运行时会太难,因为在大多数情况下性能会很糟糕。强制用户浏览每个链接将使那里发生的事情比“myList[102452]”更明显。
【讨论】: