web-dev-qa-db-ja.com

std :: listのoperator []がないのはなぜですか?

誰かがなぜoperator []がstd :: listに実装されていないのか説明できますか?少し調べてみましたが、答えが見つかりません。実装するのはそれほど難しいことではないでしょうか、それとも何かが足りないのでしょうか?

32
Gab Royer

インデックスによる要素の取得は、リンクリストの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シーケンスは、vectorで達成可能な償却一定時間(23.1.1 [lib.sequence.reqmts]/12)で実行する必要があると具体的に述べています。 dequeですが、listではありません。

実際にそのようなものが必要な場合は、std::advanceアルゴリズムを使用できます。

int iter = xs.begin();
std::advance(iter, i);
int x = *iter;
71
Pavel Minaev

(実装者にとって)それほど難しいことではありませんが、ほとんどの場合、パフォーマンスがひどいため、実行時にはそれほど難しくありません。ユーザーに各リンクを通過させると、「myList [102452]」よりもそこで何が起こっているのかが明確になります。

3
florin

私は別のSO post Extending std :: list で答えを見つけたと思います

"your operator [] is O(N) time"-これが、標準のstd :: list <>に含まれていない理由です。– Michael Burr 12月14日17:29

それでも、それが唯一の理由ですか?

編集:人々が言及したように、それは厳密にパフォーマンスよりもパフォーマンスに関する一貫性の問題であるように思われます。

1
Gab Royer

実際には、次の2つの理由から、operator []または少なくともメソッドat(int)を提供しない理由はまったくありません。

  • これは二重リンクリストであるため、インデックスを取得するには、最大でsize()/ 2の場所にイテレータを移動する必要があり、固定イテレータを内部的に保持するためのコストは非常に低くなります。そして最後に、Qtライブラリーはoperator []とatを提供しますが、それを使用した場合のパフォーマンスコストはわかりません。
  • リストは非常に使いやすいコンテナになるため、人々に使用しないものを強制することは非常に悪いプログラミング習慣です。リンクされたアクセスの近くに「ランダムアクセス」がある場合、どちらのランタイムポイントに応じて、両方のアクセスが必要な場合のさまざまな例があります。
0
Dusan