5

ベクトルの要素を反復処理するときは、インデックスの代わりに反復子を使用することをお勧めします (配列インデックスの代わりに反復子を使用する理由を参照してください)。

std::vector<T> vec;
std::vector<T>::iterator it;
for ( it = vec.begin(); it != vec.end(); ++it )
{
   // do work
}

ただし、ループの本体でインデックスを使用する必要がある場合があります。その場合、パフォーマンスと柔軟性/拡張性を考慮して、次のうちどれが望ましいでしょうか?

  1. インデックス付きループに戻る
    std::vector vec;
    size_t i;
    for ( i = 0; i < vec.size(); ++i )
    {
       // i を使用
    }
    
  2. オフセットを計算する
    std::vector vec;
    std::vector::iterator it;
    for ( it = vec.begin(); it != vec.end(); ++it )
    {
       size_t i = それ - vec.begin();
       // i を使用
    }
    
  3. std::distance を使用する
    std::vector vec;
    std::vector::iterator it;
    for ( it = vec.begin(); it != vec.end(); ++it )
    {
       size_t i = std::distance( vec.begin(), it );
       // i を使用
    }
    
4

7 に答える 7

13

ベクトルのみを使用することを計画している場合は、反復子ループよりも明確に意図を伝えるため、インデックス付きループに戻すことをお勧めします。ただし、将来のプログラムの進化によってコンテナーが変更される可能性がある場合は、イテレーターに固執し、すべての標準イテレーターで動作することが保証されている std::distance を使用する必要があります。

于 2008-09-25T09:59:47.937 に答える
8

std::distance の使用は、ランダム アクセス イテレータだけでなく、すべてのイテレータで機能するため、もう少し一般的です。そして、ランダム アクセス イテレータの場合は、It - vec.begin() と同じくらい高速である必要があります。

それ - vec.begin() は基本的にポインター演算です。

于 2008-09-25T09:36:35.447 に答える
6

std::distance(vec.begin(), it)を指していると仮定すると、インデックスitが指していることがわかりますvec

カール

于 2008-09-25T14:07:08.760 に答える
4

インデックス付きループに戻ります。

基本的に 90% のケースでイテレータが優れており、これはその 10% の 1 つです。イテレータを使用すると、コードがより複雑になり、理解しにくくなります。最初にイテレータを使用する理由は、コードを単純化することでした。

于 2008-09-25T09:37:56.897 に答える
1

必要な場合に備えてインデックスを保持しますが、それをループ条件として使用しないでください。リストでも機能し、(ループごとの) コストは O(n) と余分なレジスタです。

于 2008-09-25T11:42:24.787 に答える
0

ベクトルの場合、私は常に整数法を使用します。ベクトルへの各インデックスは、配列ルックアップと同じ速度です。値を頻繁に使用する場合は、便宜上、値への参照を作成します。

ベクトルイテレータは、ポインタ演算を使用してリストを反復処理するため、理論的にはインデックスよりもわずかに高速になる可能性があります。ただし、通常、読みやすさは実行時の違いを最小限に抑えるだけの価値があることがわかります。

私は他のコンテナタイプにイテレータを使用しますが、ループ変数が必要ない場合もあります。ただし、ループ変数が必要な場合は、ループの入力を難しくする以外は何もしていません。(c ++ 0xの自動が待ちきれません。)

于 2008-09-25T16:11:29.897 に答える
0

私は、将来の開発上の理由から、常にイテレータを使用する傾向があります。

上記の例で、std::vectorをstd::setに交換することにした場合(おそらく、要素の一意のコレクションが必要)、イテレータとdistance()を使用しても引き続き機能します。

パフォーマンスの問題は、無視できる程度に最適化されると確信しています。

于 2008-09-25T13:16:19.570 に答える