ラムダ・キャプチャーの理解

ラムダ式では、ラムダ式外で宣言された識別子を参照することができます。識別子がローカル変数または自動記憶域期間での参照の場合、上位レベルの参照であり、ラムダ式によって「キャプチャー」されなければなりません。そのようなラムダ式は、[lambda-captureopt] によって導入されます。lambda-captureopt は、識別子を参照によってキャプチャーするか、コピーによってキャプチャーするかを指定します。次の表は、lambda-captureopt の形式をまとめたものです。

シンボル

意味

[]

キャプチャーなし: 上位レベルの参照はエラーです。

[&x, y, ...]

指定どおりにキャプチャー: & プリフィックスが付加されている識別子は、参照でキャプチャーされます。その他の識別子は、コピーによってキャプチャーされます。明示的にリストされていない変数への上位レベルの参照はエラーです。

[&]

参照でキャプチャー: 上位レベルの参照は暗黙的に変数を参照でキャプチャーします。

[=]

コピーでキャプチャー: 上位レベルの参照は暗黙的に変数をコピーでキャプチャーします。

[&, x, y, ...]

参照でキャプチャー (例外あり): リストされた変数は、値/コピー (リストされていない変数は & プリフィックスが付加されています) でキャプチャーされます。

[=, &x, &y, ...]

コピーでキャプチャー (例外あり): リストされた変数は、参照でのみキャプチャーされます (リストされた変数にはすべて & プリフィックスが付加されていなければなりません)。

リストでは、識別子が 2 度リストされることはありません。area を 4 つの円の面積の合計にセットする次のコード例では、[&area,pi] は、参照で area が、コピーで pi がキャプチャーされることを示しています。

float radius[] = {2,3,5,7};
float area=0;
float pi = 3.14f;
for_each(radius, radius+4, [&area,pi](float r) {return area+=pi*r*r;}) 

デフォルト・キャプチャーの指定

デフォルト・キャプチャーを指定する場合は、リストではもう一方の種類のキャプチャーのみを指定する必要があります。つまり、デフォルト・キャプチャーを参照で指定した場合は、コピーでキャプチャーされる変数をリスト (リストのみ) しなければなりません。例えば、参照で x を、コピーで y をキャプチャーし、xy の両方が関数本体にある場合の正しいコードと誤ったコードを次に示します。

[&,&x,y]
 //ERROR - default is capture-by-reference; list only capture-by-copy variable, y
 
[&,y]
 //CORRECT - default is capture-by-reference; listed variable, y, should not have & prefix
 
[=,&x,y]  
 //ERROR - default is capture-by-copy; listed variable, x, must be prefixed with & 
 
[=,&x]  
 //CORRECT - default is capture by copy; listed variable must be prefixed with &
 
[&x]   
 //ERROR - no default capture; you must list y separately to be captured by copy
 
[y]    
 //ERROR - again no default capture is specified, so you must list &x separately to be captured by reference
 
[&x,y]   
 //CORRECT - since no default is specified, every variable is listed with its capture mode.

デフォルト・バインド・モード

次のラムダ式は、デフォルト・バインド・モードを示しています。3 つの式はすべてセマンティクス的に等価です。それぞれの式で xy は参照によりキャプチャーされ、ab はコピーによりキャプチャーされます。

[&x,&y,a,b](float r) {x=a; y=b;}
 
[&,a,b](float r) {x=a; y=b;}
 
[=,&x,&y](float r) {x=a; y=b;}

this の参照

ラムダ式がメンバー関数の中にある場合、this を参照できます。this は変数ではないため、参照によりキャプチャーすることはできません。[&] によってラムダ式で暗黙的にキャプチャーされても、それはコピーによりキャプチャーされます。


このヘルプトピックについてのフィードバックを送信

© 1996-2010 Intel Corporation. 無断での引用、転載を禁じます。