0Pricing
C++ Academy · レッスン

ラムダの値キャプチャ、参照キャプチャ、mutable

キャプチャ節を慎重に選び、ラムダの状態を理解します。

「ラムダの値キャプチャ、参照キャプチャ、mutable」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

キャプチャのまとめ

ラムダのキャプチャ節には、ラムダが使用できる周囲のスコープの変数を列挙します。キャプチャモードによって、各変数へのアクセス方法が決まります。

値によるキャプチャ

&を付けずに列挙した名前は、ラムダの作成時にコピーされます。ラムダはそのコピーを所有します。

int n = 5;
auto f = [n]() { return n * 2; };
n = 10;
std::cout << f();   // 10 (captured n was 5)

参照によるキャプチャ

&を付けた名前は、外側の変数への参照として格納されます。変更は双方に反映されます。

int counter = 0;
auto inc = [&counter]() { ++counter; };
inc(); inc();
std::cout << counter;   // 2

デフォルトキャプチャ: =

[=]は、ラムダ本体で使用されるすべての変数を値によってキャプチャします。便利ですが、意外な結果になることがあります。参照された変数だけがキャプチャされます。

int a = 1, b = 2, c = 3;
auto f = [=]() { return a + c; };   // captures a and c (not b)

デフォルトキャプチャ: &

[&]は、使用されるすべての変数を参照によってキャプチャします。ラムダがスコープより長く存続するとローカル変数への参照がダングリングするため、注意してください。

int n = 0;
auto bad = [&]() { return n; };
return bad;        // n dies, lambda dangles

モードの組み合わせ

デフォルトキャプチャと個別のキャプチャを組み合わせられます。デフォルトを上書きする変数は、個別に列挙してください。

int a = 1, b = 2;
auto f = [=, &b]() {     // a by value, b by reference
    return a + b;
};

可変ラムダ

値によってキャプチャされた変数は、ラムダ内ではconstになります。mutableを追加すると、ラムダがキャプチャしたコピーを変更できるようになります。

int n = 5;
auto inc = [n]() mutable {
    ++n;
    return n;
};
inc(); inc();
std::cout << n;   // 5 (outer unchanged)

初期化キャプチャ(C++14)

式の結果を新しい名前でキャプチャします。ムーブによるキャプチャや、計算した初期値のキャプチャが可能になります。

auto ptr = std::make_unique<int>(42);
auto f = [p = std::move(ptr)]() {
    return *p;
};
// ptr is now empty; p owns the int inside the lambda

thisのキャプチャ

メンバー関数内では、[this]によってthisポインターをキャプチャします。ラムダ内ですべてのメンバーにアクセスできます。

*thisのキャプチャ(C++17)

[*this]は、オブジェクト全体をラムダ内にコピーします。ラムダが元のオブジェクトより長く存続する場合に便利です。

落とし穴: 参照によるキャプチャと非同期処理

ローカル変数を参照によってキャプチャしたラムダを非同期に実行してはいけません。ラムダが実行される前に、ローカル変数が破棄される可能性が高いためです。

// BUG
int local = 42;
std::async([&local]() { use(local); });   // local dies, lambda dangles

クイックチェック

外側のスコープにあるstd::unique_ptrの所有権をラムダに保持させるには、どのキャプチャモードが適切ですか。

まとめ

値によるキャプチャはコピーを作成し、参照によるキャプチャは別名を作成します。デフォルトの[=]や[&]は慎重に使用してください。mutableを指定すると、値によってキャプチャしたコピーを変更できます。初期化キャプチャ(C++14)を使うと、ムーブによるキャプチャが可能になります。

よくある質問

「ラムダの値キャプチャ、参照キャプチャ、mutable」レッスンは無料ですか?

はい。「ラムダの値キャプチャ、参照キャプチャ、mutable」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「ラムダの値キャプチャ、参照キャプチャ、mutable」で何を学びますか?

キャプチャ節を慎重に選び、ラムダの状態を理解します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「ラムダの値キャプチャ、参照キャプチャ、mutable」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 関数オブジェクトとファンクター
  2. ラムダの値キャプチャ、参照キャプチャ、mutable
  3. ジェネリックラムダとクロージャ(C++14)
  4. std::functionによる型消去可能な呼び出し可能オブジェクト
← C++ Academyに戻る