C++ 为什么不是';std::list是否有运算符[]?

C++ 为什么不是';std::list是否有运算符[]?,c++,list,stl,C++,List,Stl,谁能解释一下为什么没有为std::list实现操作符[]?我找了一下,但没有找到答案。这不会太难实现,或者我遗漏了什么吗?这不会太难(对于实现者来说),但在运行时会太难,因为在大多数情况下性能会很糟糕。强制用户浏览每个链接将比“myList[102452]”更清楚地显示其中的内容。按索引检索元素是链表的O(n)操作,这就是std::list的含义。所以决定提供操作符[]是有欺骗性的,因为人们可能会主动使用它,然后你会看到这样的代码: std::list<int> xs; for

谁能解释一下为什么没有为std::list实现操作符[]?我找了一下,但没有找到答案。这不会太难实现,或者我遗漏了什么吗?

这不会太难(对于实现者来说),但在运行时会太难,因为在大多数情况下性能会很糟糕。强制用户浏览每个链接将比“myList[102452]”更清楚地显示其中的内容。

按索引检索元素是链表的O(n)操作,这就是
std::list
的含义。所以决定提供
操作符[]
是有欺骗性的,因为人们可能会主动使用它,然后你会看到这样的代码:

 std::list<int> xs;
 for (int i = 0; i < xs.size(); ++i) {
     int x = xs[i];
     ...
 }

我想我在另一个SO帖子中找到了答案

“您的操作员[]是O(N)时间”-此 这就是为什么它不包括在 本标准的标准::列表迈克尔 伯尔12月14日17:29

不过,这是唯一的原因吗


编辑:似乎正如人们所提到的,性能的一致性比严格的性能更重要。

实际上,完全没有理由不提供运算符[]或至少方法at(int),原因有两个:

  • 它是一个双链表,所以您需要移动最多size()/2个位置的迭代器来获取索引,并且在内部保留几个固定迭代器的成本非常低。最后,Qt库提供了操作符[]和at,我看不到使用它的性能成本
  • 强迫人们不要使用某些东西是一个非常糟糕的编程习惯,因为列表将是非常有用的容器,如果您在链接访问附近有一个“随机访问”,那么当您需要这两个访问时,有各种各样的示例,这取决于在哪个运行时点

详细说明位运算符[]在所有其他使用位置都是一个恒定时间操作。给O(n)操作赋予相同的名称将是不一致和令人困惑的。在映射中,它显然不是位置索引,这一点很明显——除非映射键是整数,但如果您将位置访问与键查找混淆,您已经有了更大的问题;)我知道区别,请放心!但它仍然是运算符[];)。所以基本上,这只是防止人们犯错的问题?是的。或者不做出你无法兑现的承诺。在STL中,运算符[]承诺有效访问任意元素。请注意,std::list::size()也可以是O(n)(请参阅),因此,即使不调用运算符[],第一个循环也可以是O(n^2)。
std::next
是更合适的函数(
std::listlist;…;*std::next(std::begin(list),index)=1;
),因为。你是说这还不够理由吗?:-)它是。从别处看,.NET
LinkedList
没有提供索引器,原因大致相同——它太具有欺骗性了。传统上,当某物具有位置索引器时,假定操作为O(1)。这纯粹是基于您的观点,还是您创建了一个很好的测试场景,在该场景中,您展示了
std::list::operator[]
的自定义实现是有效的?(顺便说一句,根据Stroustrup,您应该使用的标准容器是
std::vector
)。
int iter = xs.begin();
std::advance(iter, i);
int x = *iter;