C++ 11では、次のようにコンテナを反復処理できます。
for(auto i : vec){
std::cout << i << std::endl;
}
しかし、私はこれが不必要に-不必要にであることを知っています、なぜなら私はprintvec
の値---([〜#〜] edit [〜#〜]:の各要素)vec
のコピーを作成するため、代わりに行う:
for(auto &i : vec){
std::cout << i << std::endl;
}
しかし、私はvec
の値が決して変更されず、const-correctnessを順守することを確認したいので、次のことができます。
for(const auto &i : vec){
std::cout << i << std::endl;
}
だから私の質問は次のとおりです:コンテナの値を見るだけでlookが必要な場合、最後のループではありません(const auto &i
)([〜#〜] edit [〜#〜]:の各要素)vec
?の余分なコピーを持たないことにより効率が向上するため、常に優先されます。
私は開発中のプログラムを持っています。このプログラムでは効率が非常に重要であるため(最初にC++を使用する理由)、全体を通してこの変更を検討しています。
はい。引数を読み取るだけの場合と同じ理由で、パラメータconst&
を作成します。
T // I'm copying this
T& // I'm modifying this
const T& // I'm reading this
これらは「デフォルト」です。ただし、T
が基本型(ビルトイン)の場合、コピーはエイリアスよりも安価であるため、通常は読み取り用にconst T
(参照なし)に戻ります。
効率が非常に重要であるため、全体を通してこの変更を行うことを検討しているプログラムを開発しています
ベクトルに文字列が含まれていると想像してください。長い文字列。 5000の長い文字列。それらを不必要にコピーすると、ひどく非効率的なforループがうまく書かれてしまいます。
コードが意図に従っていることを確認してください。ループ内でコピーが必要ない場合は、コピーを作成しないでください。
上記のように参照&を使用するか、反復子を使用します。
免責事項:一般に、auto
とauto&
の違いは微妙で、一部はスタイルの問題ですが、時には正確性の問題もあります。ここでは一般的なケースをカバーするつもりはありません!
Forループに基づく範囲では、
for (auto element : container) {}
そして
for (auto& element_ref : container) {}
element
はcontainer
内の要素のコピーであり、element_ref
はコンテナ内の要素への参照です。
アクションの違いを確認するには、次の例を検討してください。
#include <iostream>
int main(void) {
int a[5] = { 23,443,16,49,66 };
for (auto i : a) i = 5;
for (const auto& i : a) std::cout << i << std::endl;
for (auto& i : a) i = 5;
for (const auto& i : a) std::cout << i << std::endl;
}
印刷します
23
443
16
49
66
5
5
5
5
5
なぜなら、最初のループは配列要素のコピーに対して機能し、2番目のループは実際に配列内の要素を変更するからです。
要素を変更したくない場合、多くの場合、const auto&
の方が適切です。これは、要素のコピーを回避するためです(高価になる可能性があります)。