2016-10-20 9 views
1

C++の初心者で、私はイテレータを発見しています。私はいずれかのコンテナを通してループのためにintまたはiteratorsを使用できることを認識しています。例えば一般C++の整数または反復子とのループの相違点

  • 、話す

    i is an int: 1 4 8                                 
    i is an iterator: 1 4 8 
    

    を出力

    #include <iostream> 
    #include <vector> 
    
    int main() 
    { 
        std::vector<int> v; 
        v.push_back(1); 
        v.push_back(4); 
        v.push_back(8); 
    
        std::cout << "i is an int: "; 
        for (int i = 0; i<v.size();i++) 
        { 
         std::cout << v[i] << " "; 
        } 
        std::cout << std::endl; 
    
        std::cout << "i is an iterator: "; 
        for (std::vector<int>::iterator i = v.begin(); i!=v.end();i++) 
        { 
         std::cout << *i << " "; 
        } 
        std::cout << std::endl; 
    } 
    

    は、1つまたは他の方法を使用して任意の利点があると考えますか?

  • もう一方よりも速いのですか?
  • いつintを使用し、iteratorを使用する必要がありますか?
+1

C++ 11以降では、次のような範囲でも使用できます:for(int e:v){std :: cout << e << ""; } ' – Jarod42

+1

また' auto i = v.begin() 'を実行することもできますので、型の比較的複雑な名前を指定する必要はありません – ForceBru

+0

' int'バージョンはすべてのコンテナで一般化することはできません( 'list'、' set'など)、反復子(および上記に基づく範囲)は可能です。 – Chad

答えて

2

イテレータの主な理由は、一般性を提供することです。具体的には、一般的なアルゴリズムは、そのタイプのテンプレートパラメータとして渡されたイテレータを使用して様々な容器を通過することができます

template <class InIt> 
void print(InIt b, InIt e) { 
    while (b != e) { 
     std:cout << *b << ' '; 
     ++b; 
    } 
} 

この場合、あなたはlistまたはmapを(印刷することができますので、あなたは、イテレータから利益を得ますちょうど2つの例を挙げると)vectorのように。

既知のタイプのコンテナで直接作業している場合は、それほど問題にはなりません。実際にはvectorの項目を印刷したい場合は、インデックスに整数を使って完全にうまく動作します。イテレータの代わりにインデックスを使用すると、そのコンテンツを読み込むのではなく、コレクションを変更する場合に利点があります。たとえば、ループ内のベクトルにpush_backを実行すると、整数インデックスは有効のままですが、イテレータは無効になる可能性があります。。

for (auto i : v) 
    std::cout << i << ' '; 

1.注:あなたが示してきた場合については

は、しかし、あなたはおそらくインデックスまたはイテレータのいずれかを使用して回避するために、範囲ベースforループを検討したいですこれは標準的なイテレータにも当てはまりますが、本当に必要な場合にはこのような状況で有効なイテレータ型を作成することが可能です。です。例えば:1、または他の方法を使用してのいずれかの利点がある :https://stackoverflow.com/a/7958561/179910

1

時々、あなたのアルゴリズムは、インデックスを必要とし、この場合には、インデックスを追跡するために、int、またはsize_tを使用します。それ以外の場合はイテレータを使用します。また、いくつかのコンテナはイテレータでしかトラバースできないことに注意してください。 list,mapなど

0

より一般的です。反復子を使用して、合理的に索引付けできないシーケンスを反復することができます(そのため、いくつかの文字がstd::iterator categoriesになります)。たとえば、標準入力はistream_iteratorで反復処理され、std::listはインデックスをサポートしません。

一方、インデックスは、コンパイラが最適化するのは簡単ですが、インターフェイスに関してはるかに厳密です。

言われているように、イテレータの使用法は現代のC++では遍在しています。特に重大な型の命名を避けるために型減算を使うことができるので、それは悪いデフォルトではありません。

生のループの代わりのアルゴリズムを使用して、古いスタイルにranged-forループを好むがループ:

for(auto const& elem : range){ 
    //... 
} 
0

Similar question already exists は、私はあなたが一度に一つの疑問に答えるためにしてみましょうか? intはいつ使うべきですか?イテレータはいつ使うべきですか? 整数を使用できない場合があり、イテレータを使用する必要があります。しかし反復子は一般に整数よりも遅い。

What are the best and common practices? 

これはアルゴリズムによって異なります。固定サイズの配列を反復処理する場合は、単純で簡単な整数を使用します。 STLを使用している場合や独自のデータ構造(リンクリストをインスタンスとして)を開発している場合は、イテレータを使用することをお勧めします。

関連する問題