特にforループでauto
キーワードを使用する利点と欠点は何ですか?
for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->something();
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
it->second->something();
}
for(auto it = x.begin(); it != x.end(); it++ )
{
it->??
}
マップまたはベクターのイテレータがあるかどうかわからない場合は、first
またはsecond
を使用するか、オブジェクトのプロパティに直接アクセスするかどうかはわかりません。 ?
これは、キーワードvar
を使用するかどうかに関するC#の議論を思い出させます。私がこれまでに得ている印象は、C++の世界では、人々はauto
キーワードを採用する準備ができており、C#の世界のvar
よりも少ない争いであるということです。私にとって最初の本能は、変数の型を知りたいので、その変数に対して実行できるはずの操作を知ることができます。
メタプログラミングなどのために、C#型よりも型が非常に複雑で複雑になる可能性があるため、C++での動機はさらに極端です。 auto
は、明示的なタイプよりも書き込みと読み取りが高速であり、より柔軟/保守可能です。つまり、入力を開始しますか
boost::multi_map<NodeType, indexed_by<ordered_unique<identity<NodeType>>, hashed_non_unique<identity<NodeType>, custom_hasher>>::iterator_type<0> it
それは完全なタイプでさえありません。いくつかのテンプレート引数を見逃しました。
あなたの例では:
for(auto it = x.begin(); it != x.end(); i++)
{
it->??
}
x
visibleの宣言が必要です。したがって、it
のタイプは明白です。 x
のタイプが明確でない場合、メソッドが長すぎるか、クラスが大きすぎます。
異議!読み込まれた質問。
3つ目のコードに??
が含まれているのに、1つ目と2つ目のコードには含まれていない理由を教えてください。公平を期すために、コードは次のように読み取る必要があります。
for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
{
it->???
}
for(std::map<T>::iterator it = x.begin(); it != x.end(); i++)
{
it->second->???
}
そこ。 auto
を使用していなくても同じ問題。
そして、すべての場合において、答えは同じです:コンテキストが重要です。コードの一部について単独で意味のある話をすることはできません。テンプレートではなく具体的な型を使用したとしても、コードの読者は型の宣言について知っておく必要があるため、問題が別の場所に移動しただけです。
これらの状況でauto
を使用するとコードが判読不能になる場合は、コード設計に問題があることを警告する記号として扱う必要があります。もちろん、ビット操作やレガシーAPIを扱う場合など、低レベルの詳細が重要な場合もあります。その場合、明示的な型が読みやすくなることがあります。しかし、一般的には-いいえ。
var
については(明示的に言及したため)、C#コミュニティにはvar
を使用した vast consensus もありますfor。その使用に反対する議論は一般的に 誤解に基づいて構築された です。
あなたのコード:
for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
テンプレートに依存する名前のため、コンパイルされません。
これは正しい構文です:
for( typename std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
型宣言の長さを見てください。これは、auto
キーワードが導入された理由を示しています。この :
for( auto it = x.begin(); it != x.end(); i++)
より簡潔です。だから、これはプロです。
あなたは少し注意する必要があります。キーワードauto
を使用すると、宣言した型を取得できます。
例えば :
std::vector< int > v{ 1, 2, 3, 4 };
for ( auto it : v )
{
++ it; // ops modifying copies of vector's elements
}
対
std::vector< int > v{ 1, 2, 3, 4 };
for ( auto & it : v ) // mind the reference
{
++ it; // ok, vector's elements modified
}
結論として:はい、それをすべきですが、使いすぎないでください。一部の人々はそれを使いすぎて、次の例のようにautoをどこにでも置く傾向があります:
auto i = 0;
対
int i = 0;
はい、そうすべきです! auto
はタイプを消去しません。 x.begin()
が「わからない」場合でも、タイプを誤って使用しようとすると、コンパイラーはそれを認識し、エラーを報告します。また、map
をvector<pair<Key,Value>>
でエミュレートすることは珍しいことではないため、auto
を使用するコードは両方の辞書表現で機能します。
はい、デフォルトのルールとしてauto
を使用する必要があります。タイプを明示的に指定するよりもメリットがあります。
ここで選択できます。選択肢がない場合もあります:
auto
の機能を正確に理解していれば、欠点はありません。