C++
C++でJavaScriptのクロージャのようなことをしてみる
C++は関数がクロージャになることはできない。
JavaScriptはすべての関数がクロージャとなるので、関数内に関数を書いても、内側関数から外側関数のローカル変数にアクセスできる。(かのように見える)
そのため直感的なコードを書くことが可能になっている。
なので、関数から無名関数を返しても、外側関数のローカル変数がまだ生き続けているかのようにアクセスすることができるわけだ。(元々のローカル変数はスコープアウトした時に消えている)
こういう仕組みをクロージャという。
PHPのように関数内関数は書けるものの関数がクロージャになれない言語の場合は、内側関数から外側関数のローカル変数にはアクセスできないので、直感とは反した感じになる。(そのかわりPHPは無名関数がクロージャになれるので、関数内には無名関数を書くのが定番だ)
C++は関数内関数を書くことができない言語だが、ラムダ式(関数オブジェクト)があり、それにキャプチャ機能があるので、クロージャと似たようなことができる。
値キャプチャをして、mutable修飾子を付けると、キャプチャした変数の値を変更できるようになる。
その値はラムダ式内に保持されているので、呼び出すたびにカウンタが増えていくというようなラムダ式を作ることができるわけだ。
ちなみに参照キャプチャすると、外側関数が終了した時点でローカル変数がスコープアウトしてしまって、ラムダ式内の x がダングリング状態になるので注意。(この辺の挙動が本物のクロージャとは違う。PHPの無名関数はuseで参照渡ししてもアクセスし続けられる)
|