227

私は C++ 言語が初めてです。私はベクトルを使い始めましたが、インデックスを介してベクトルを反復処理するすべてのコードで、forループの最初のパラメーターは常にベクトルに基づくものであることに気付きました。Java では、ArrayList を使用して次のようなことを行う場合があります。

for(int i=0; i < vector.size(); i++){
   vector[i].doSomething();
}

これが C++ で表示されない理由はありますか? それは悪い習慣ですか?

4

13 に答える 13

175

あなたがそのような慣習を見ない理由は非常に主観的であり、明確な答えを得ることができません。なぜなら、私はiteratorスタイルコードではなくあなたの言及した方法を使用するコードの多くを見たからです。

vector.size()以下は、人々がループの方法を考慮しない理由である可能性があります。

  1. size()ループ状態で毎回呼び出すことについて妄想的であること。ただし、問題がないか、簡単に修正できます。
  2. ループ自体std::for_each()よりも優先for
  3. 後でコンテナstd::vectorを別のコンテナに変更すると(たとえば map、 )、すべてのコンテナがループのスタイルをlistサポートしているわけではないため、ループメカニズムの変更も必要になります。size()

C ++ 11は、コンテナー内を移動するための優れた機能を提供します。これは「範囲ベースのforループ」(またはJavaでは「拡張forループ」)と呼ばれます。

少しのコードで、完全にトラバースできます(必須です!)std::vector

vector<int> vi;
...
for(int i : vi) 
  cout << "i = " << i << endl;
于 2012-10-03T06:10:36.610 に答える
134

ベクトルを繰り返し処理する最もクリーンな方法は、反復子を使用することです。

for (auto it = begin (vector); it != end (vector); ++it) {
    it->doSomething ();
}

または(上記に相当)

for (auto & element : vector) {
    element.doSomething ();
}

C++0x より前では、auto を iterator 型に置き換え、グローバル関数 begin と end の代わりにメンバー関数を使用する必要がありました。

これはおそらくあなたが見たものです。あなたが言及したアプローチと比較して、利点は、のタイプに大きく依存しないことですvectorvector別の「コレクション型」クラスに変更しても、コードはおそらく引き続き機能します。ただし、Java でも同様のことができます。概念的に大きな違いはありません。ただし、C++ はテンプレートを使用してこれを実装します (Java のジェネリックと比較して)。したがって、このアプローチは、静的配列などの非クラス型であっても、関数が定義されbeginているすべての型で機能します。endここを参照してください:範囲ベースの for はプレーン配列でどのように機能しますか?

于 2012-10-03T05:54:59.810 に答える
129

C++ でこれが表示されない理由はありますか? それは悪い習慣ですか?

いいえ。これは悪い習慣ではありませんが、次のアプローチはコードに一定の柔軟性を与えます。

通常、C++11 より前のコンテナー要素を反復処理するためのコードでは、次のような反復子が使用されます。

std::vector<int>::iterator it = vector.begin();

これは、コードがより柔軟になるためです。

すべての標準ライブラリ コンテナはイテレータをサポートし、提供します。開発の後半で別のコンテナーに切り替える必要がある場合、このコードを変更する必要はありません。

注:考えられるすべての標準ライブラリ コンテナーで動作するコードを記述することは、思ったほど簡単ではありません。

于 2012-10-03T05:59:27.583 に答える
44

それを行う正しい方法は次のとおりです。

for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
    it->doSomething();
 }

ここで、T はベクトル内のクラスの型です。たとえば、クラスが CActivity の場合、T の代わりに CActivity と記述します。

このタイプの方法は、すべての STL で機能します (ベクトルだけでなく、少し優れています)。

それでもインデックスを使用したい場合は、次の方法があります。

for(std::vector<T>::size_type i = 0; i != v.size(); i++) {
    v[i].doSomething();
}
于 2012-10-03T05:57:14.373 に答える
12

auto 演算子を使用すると、ベクターやその他のデータ構造のデータ型やサイズを気にする必要がないため、本当に使いやすくなります。

auto および for ループを使用した反復ベクトル

vector<int> vec = {1,2,3,4,5}

for(auto itr : vec)
    cout << itr << " ";

出力:

1 2 3 4 5

このメソッドを使用して、セットとリストを反復することもできます。autoを使用すると、テンプレートで使用されているデータ型が自動的に検出され、使用できるようになります。そのため、vectorofstringまたはchar同じ構文があったとしても、問題なく機能します。

于 2019-11-22T17:09:30.090 に答える
6

ベクトルで値を反復して出力する簡単な方法を次に示します。

for(int x: A) // for integer x in vector A
    cout<< x <<" "; 
于 2020-04-08T08:00:04.470 に答える
4

STL ではiterators、イテレータは抽象的な概念であり、すべての標準コンテナに実装されているため、プログラマはコンテナをトラバースするために を使用します。たとえば、std::listまったくありませんoperator []

于 2012-10-03T05:59:43.987 に答える