2017-07-22 6 views
0

SOドキュメントで説明したラムダ関数の呼び出しに関する質問があります。C++でのLambda関数

int multiplier = 5; 
auto timesFive = [multiplier](int a) { return a * multiplier; }; 
std::cout << timesFive(2); // Prints 10 

multiplier = 15; 
std::cout << timesFive(2); // Still prints 2*5 == 10 

なぜ2 * 15 = 30が印刷されないのですか? 明らかに、乗数の値は変更されており、timesFiveへの呼び出しが行われると、multiplierという更新された値が選択されます。

答えて

2

multiplierは、ラムダ関数が作成されるときにがクロージャオブジェクト内にコピーされます。

外部機能のローカルにあるmultiplierを変更することができます。ただし、クロージャ内のコピーは、作成時の値にとどまります。

あなたが期待される結果は、あなたがキャプチャリスト内&multiplierを指定して参照、すなわちによってmultiplierを撮影した場合、あなたが得るだろうものです。この最後のケースでは、ラムダが参照によってキャプチャされた変数よりも長持ちしないことを確認する責任はあなたのものに過ぎないことに注意してください。あなたのラムダが含まれている関数のローカルのみであれば、それはすべて問題ありませんが、それを返すか(例えばstd::function変数の中に)別の場所に格納しておき、親関数が返された後に呼び出すと、参照による

1

キャプチャ乗数:

だけ&multiplierの代わりmultiplierを使用します。

auto timesFive = [&multiplier](int a) { return a * multiplier; }; 
3

あなたはないことではなく、参照によってキャプチャする必要があります。

あなたがにリンクされているラムダ関数のSOのドキュメントは言った:

[]キャプチャリストです。デフォルトでは、囲みスコープの変数にラムダでアクセスすることはできません。 をキャプチャすると、コピーまたは参照のいずれかとして、ラムダ内で変数にアクセスできるようになります。 キャプチャされた変数はラムダの一部になります。は関数の引数とは異なり、ラムダを呼び出すときに渡す必要はありません。

int a = 0;      // Define an integer variable 
auto f = [a]() { return a*9; }; // OK, 'a' is "captured" by value 
auto f = [&a]() { return a++; }; // OK, 'a' is "captured" by reference 
関連する問題