質問: 以下のコードがコンパイルできないのは何故なんでしょうか? ``` void f() { int x; +[x]{}; } ``` 一見コンパイルできると思ったのですが、GCCでもClangでもMSVCでもコンパイルエラーでした。 なお以下はコンパイルできるようです。 ``` void f() { +[]{}; } ```
回答: > > C++のラムダ関数がローカル変数をキャプチャするときに関数ポインタに変換できなくなるのはなぜ? > > > 短い答え:C++実行環境において合理的な実装が不可能なためです。 思考実験として下記の関数`g`を考えます。関数`g`は「実行時に値が確定するローカル変数`x`を(コピー)キャプチャした関数ポインタ」を返す必要があります。 ``` auto g() { int x; std::cin >> x; // ラムダ式から関数ポインタへの変換に単項+演算子を利用 return +[x]{}; } ``` この関数ポインタがさす先の実行可能コード(≒機械語命令列)はコンパイル時には生成不可能であり、プログラム実行時に実行可能コードを動的生成しなければなりません。また関数`g`が何度も呼び出されるシナリオでは異なる`x`値に応じた実行可能コードが必要となりますが、C++言語はガベージコレクタをもたないため実行可能コード片(≒動的に生成される関数)を破棄する契機がなくメモリを圧迫し続けます。