2012-01-09 4 views
26

C++ 11でのコンテナの反復処理の推奨方法は何ですか?C++ 11でのコンテナの反復処理の推奨方法は何ですか?

任意の場合、一方が他方よりも優先されると、

container.begin() and container.end() 

それとも

begin(container) and end(container) 

を使用していますか?

+4

あなたの例は、それ自体を反復することとは関係ありません。それは、コンテナのモデルであるクラスのオブジェクトからイテレータを取得する方法です。 – pmr

+5

推薦状を持っている経験はまだありません。新しいfor構文とbegin/end free関数には利点がありますが、経験が教えてくれる欠点があるかもしれません(私は何も期待しませんが、 – AProgrammer

答えて

24

それは、より拡張性だから良い方法は

begin(container) 
end(container) 

です。たとえば、テンプレート引数の減算を使用して静的配列のサイズを判断することができます。したがって、begin(my_static_array)end(my_static_array)が機能します。

さらに一般的には、オーバーロード/特殊化を追加してend(。)(。)を開始し、不変のレガシータイプを汎用アルゴリズムで使用できます。

あなたはクライアントコードでyouself

template <typename T> 
void foo (T & t) 
{ 
    bar (begin(t), end(t)); // certainly better than bar(t.begin(), t.end()) 
} 

一般的なアルゴリズムを書いている場合は、実際には、それはあまり重要ではありません。このことを心配する必要があります。実際、私はと言うでしょうはその場合に新しいフォームを使用しない - 私は特定の状況のた​​めに特定のスタイル/イディオムを予約したい、私の考え方を分割するのが好きです。しかし、それは私だけです。

for (auto i = c.begin(); i != c.end(); ++i) 
    // I can see at-a-glance that c is a STL-style container. 
    // That might be useful to know. I can probably dismiss static arrays 
    // and unorthodox containers as possibilities. 
    foo (i, c.size()); 
+0

ここでイテレータへの参照はなぜですか? – Useless

+0

私は 'for(auto&i:c)'でスクランブルされているので、今削除されました。ありがとう。 – spraff

+4

配列に対して反復処理を有効にするには、 'std :: begin(t)'と 'std :: end(t)'のどちらかを書かなければなりません。 'std :: end;'を関数内の最初の2つのステートメント( 'std :: swap'を使っているようなもの)で' using std :: end; ' – fredoverflow

37

私はrange based for loops

for (auto item : container) 

との新しい構文は、ほとんどのC++ 11が好きだろうと思います。

他の人がコメントしたように、の代わりにauto&またはconst auto&が必要な場合があります。

+0

@Basile:私は同意しますが、VS10はそれをまだサポートしていないので、私はまだそれと遊んでいません。 :) –

+0

@spraff:同意しましたが、質問は(意図的に)漠然としていて、私の答えは合っています! –

+11

不要なコピーを避けるために、項目を参考にして、 'auto&item:container'としましょう。 – Xeo

関連する問題