私が読んでいる本は、反復するときにこの例を提供しますvector
for (auto &e: v) {
cout << e << endl;
}
vがとして宣言されていると仮定しvector<int> v
ます。つまり、このコレクション内の要素のタイプがであることがわかっていint
ます。
何らかの方法で使用auto
する方が良いですか、それとも優先されますか?
for (int &e: v) {
cout << e << endl;
}
なんで?
はい。auto
が好ましい。fromの宣言を変更した場合v
:
std::vector<int> v; //before
これに:
std::vector<float> v; //after
で使用する場合int &
はfor
、それも変更する必要があります。しかし、でauto
、変更する必要はありません!
私の意見では、での作業auto
は多かれ少なかれインターフェースへのプログラミングに似ています。したがって、ループ内で操作を実行し、ループ変数のタイプが操作をサポートしている限り、+=
そのタイプを気にしない場合は、次の解決策があります。e
+=
auto
for(auto & e : v)
{
e += 2;
}
この例では、右側にあるe
サポート+=
のタイプを気にする必要があります。int
を定義したユーザー定義の型operator+=(int)
、または からの暗黙的な変換をサポートする型のoperator+=(T)
場合でも機能します。これは、インターフェースをプログラミングしているようなものです。T
int
std::vector<Animal*> animals;
animals.push_back(new Dog());
animals.push_back(new Cat());
animals.push_back(new Horse());
for(size_t i = 0 ; i < animals.size(); ++i)
{
animals[i]->eat(food); //program to interface
}
もちろん、このループを次のように記述します。
for(Animal * animal : animals)
{
animal->eat(food); //still program to interface
}
または単にこれ:
for(auto animal : animals)
{
animal->eat(food); //still program to interface
}
それはまだインターフェースへのプログラミングです。
しかし同時に、@Davidのコメントのポイントは注目に値します。
最初の例では、ベクトルの要素への依存度が低くなっています。
1か月以内に、ベクトルに大きな整数を格納する必要があるため、、std::vector<int64_t>
またはその他の幅の広い型を使用する必要があるとします。これで、そのベクトルを反復処理するすべてのコードが無効になります。それぞれを変更する必要があります。
for (int &e: v) {}
のために:
for (int64_t &e: v) {}
そのためauto
、内部型を推測する方がよいのです。そうすれば、ベクターに格納されているタイプを別の互換性のあるタイプに変更でき、すべてのコードが引き続き機能します。