以下の場合を考える。
class Foo { int x ; public : void f() { // f()の中で百個の自動変数を使う。 int val001, val002, val003, /*...*/ val100 ; // lambda expression [&]{// #1 // ここで、valXXXなる一連の変数を全部使いたい。 // さらにlambda expression [&] {// #2 // ここで、#1の直前のメンバ関数であるf()のthisを使いたい。 // と同時に、valXXXなる一連の変数も使いたい。 this->x = val001 ; }() ; }() ; } } ;
上記のコードは、おそらく失敗するであろうと思われる。というのも、lambdaは直前の自動変数しかキャプチャできないからだ。#1のキャプチャリストに、明示的に書いたとしても、#2で使うことは出来ない。なぜならば、キャプチャした変数は、lambdaのクロージャオブジェクトのメンバ変数という扱いだからだ。従って、上記コードの正しい例はこうなる、と思う。
class Foo { int x ; public : void f() { // f()の中で百個の自動変数を使う。 int val001 = 1, val002 = 2, val003 = 3, /*...*/ val100 = 100 ; // lambda expression [&]{// #1 auto auto_val001 = val001 ; // 使う必要のあるvalXXXを、ここで全部明示的に自動変数に代入。 // さらにlambda expression [&] {// #2 this->x = auto_val001 ; }() ; }() ; } } ;
たとえ、#2でthisをキャプチャしても、それは#1のlambdaのクロージャオブジェクトのthisにはならない。#1の直前のメンバ関数のthisになる。したがって、this->val001などとやって、#2から#1のキャプチャした変数を全部使うなどと言う抜け道はない。もし本当に使いたいのであれば、#1のcompound-statement内で、地道に必要な変数を全部、自動変数に代入してやる必要がある。
どうも、lambdaのネストは使いづらいな。
追記:#2のthisは#1のキャプチャしたthisであり、つまり#1を直接包括するメンバ関数のthisなので、thisを自動変数にする必要はない。
No comments:
Post a Comment