本文へスキップ
BecomeCoder

C++コース · 第8章 std::vector と範囲for ― 伸び縮みする配列 · レッスン33

auto と範囲for ― すっきり書く

ブラウザで完結

導入

コンテナを1つずつ処理するとき、for (int i = 0; ...) は書くのが面倒でミスも起きがちです。モダンな C++ には「範囲for」と auto があり、ぐっと読みやすく書けます。

説明

auto は「型をコンパイラに推論させる」キーワードです。長い型名を書かずに済みます。範囲for for (要素 : コンテナ) は、先頭から末尾まで自動で回します。

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main() {
    vector<string> fruits = {"りんご", "みかん", "ぶどう"};

    for (auto f : fruits) {      // auto が string に推論される
        cout << f << endl;
    }
    return 0;
}

ここで大事なのが「コピーか、参照か」です。for (auto f : v) は要素をコピーします。書き換えたいときや、大きな要素を効率よく回したいときは &(参照)を付けます。

flowchart TB
  a["for (auto x : v)<br/>コピー。元は変わらない"]
  b["for (auto&amp; x : v)<br/>参照。x への変更が元に反映"]
  c["for (const auto&amp; x : v)<br/>参照だが読み取り専用(推奨)"]
  a --- b --- c
#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v = {1, 2, 3};

    for (auto& x : v) {    // 参照なので元の要素を書き換えられる
        x *= 10;
    }
    for (const auto& x : v) {  // 読み取りだけなら const auto& が効率的
        cout << x << " ";      // 10 20 30
    }
    cout << endl;
    return 0;
}

まとめ

読み取るだけなら for (const auto& x : v)、書き換えるなら for (auto& x : v) が基本形です。auto は便利ですが、コピーになる for (auto x : v) は大きな要素だと無駄が出る点を意識しましょう。

実際に動かしてみよう

下のエディタにC++を書いて「コンパイル & 実行」を押すと、ブラウザ内で本物のC++コンパイラ(clang + libc++)がその場でコンパイルして実行し、出力が表示されます。std::string・vector・クラス・テンプレート・STL などモダンC++がそのまま動きます。本文の例を書き換えて試しながら進めましょう(初回だけコンパイラの読み込みに時間がかかります。以降はキャッシュされます。この回は標準入力(cin)は使わず、値はコードに直接書きます)。

C/C++ — ブラウザ内で本物のコンパイラで実行

ブラウザ内で本物のC/C++コンパイラ(clang + libc++ / WebAssembly)を動かします。構造体・malloc/free・std::string・vector・クラス・テンプレート・STL などがそのまま実行できます(初回のみコンパイラの読み込みに時間がかかります。以降はブラウザにキャッシュされます)。
スクロールして表示された時点でも自動で読み込まれます。