web-dev-qa-db-ja.com

C ++ 11範囲ベースのループ:値またはconstへの参照によって項目を取得

範囲ベースのループの例をいくつか読んで、2つの主な方法を提案します。 12 、、 4

std::vector<MyClass> vec;

for (auto &x : vec)
{
  // x is a reference to an item of vec
  // We can change vec's items by changing x 
}

または

for (auto x : vec)
{
  // Value of x is copied from an item of vec
  // We can not change vec's items by changing x
}

まあ。

IMOのvecアイテムを変更する必要がない場合、例では2番目のバージョン(値による)を使用することを推奨しています。 constが参照するものを提案しない理由(少なくとも直接的な提案は見つかりませんでした):

for (auto const &x : vec) // <-- see const keyword
{
  // x is a reference to an const item of vec
  // We can not change vec's items by changing x 
}

良くないですか? constである間に、各反復で冗長コピーを回避しませんか?

181
deepmax

avoidコピーを作成するだけでなく、アイテムを変更したくない場合は、auto const &が正しい選択です。

for (auto const &x : vec)

auto &の使用を勧める人は誰でも間違っています。それらを無視します。

要約は次のとおりです。

  • コピーを使用する場合は、auto xを選択します。
  • 元のアイテムを使用して変更する場合は、auto &xを選択します。
  • 元のアイテムを操作する場合は、auto const &xを選択し、変更しません。
326
Nawaz

std::vector<int>またはstd::vector<double>がある場合は、autoまたはintをコピーするのが安価であるため、const auto&の代わりにdouble(値のコピーを使用)を使用しても問題ありません。

for (auto x : vec)
    ....

しかし、MyClassにいくつかの重要なコピーセマンティクス(たとえば、std::vector<MyClass>、いくつかの複雑なカスタムクラスなど)があるstd::stringがある場合は、const auto&を使用してディープコピーを回避することをお勧めします

for (const auto & x : vec)
    ....
21
Mr.C64

vecアイテムを変更する必要がない場合、最初のバージョンを使用することをお勧めします。

それから彼らは間違った提案をします。

Constが参照するものを提案しない理由

彼らは間違った提案を与えるからです:-)あなたが言うことは正しいです。 observeオブジェクトだけが必要な場合、コピーを作成する必要はなく、_const以外の参照を持つ必要もありません。

編集:

リンクする参照はすべて、int値の範囲またはその他の基本的なデータ型を反復処理する例を示しています。その場合、intのコピーは高価ではないため、コピーの作成は基本的に、const &を観察することと同等です(より効率的でない場合)。

ただし、これは一般的にユーザー定義型には当てはまりません。 UDTはコピーに費用がかかる場合があり、コピーを作成する理由がない場合(元のオブジェクトを変更せずに取得したオブジェクトを変更する場合など)、const &を使用することをお勧めします。

3
Andy Prowl

ここで反対になりますが、forループに基づく範囲ではauto const &は必要ありません。次の関数が馬鹿げていると思ったら教えてください(その目的ではなく、書かれている方法で):

long long SafePop(std::vector<uint32_t>& v)
{
    auto const& cv = v;
    long long n = -1;
    if (!cv.empty())
    {
        n = cv.back();
        v.pop_back();
    }
    return n;
}

ここで、著者はvを変更しないすべての操作に使用するvへのconst参照を作成しました。これは私の意見では愚かであり、auto const &auto &だけではなく、forループに基づく範囲の変数。

1