問題は、それがどこかに保存されているため、ローカル変数は、ローカルの「所有者」(生存ラムダによって参照により捕捉された場合、すなわち、C++ラムダ「はupwards funarg」事件を解決することができないということですまたは関数の結果として返されたため)。
ラムダが参照によって変数をキャプチャするとき、C++はラムダコードによって使用されるコンテキスト構造に参照される変数のアドレスを格納するだけです。
ただし、変数自体はローカルであり、ラムダが作成されたスタックフレームに存在します。ラムダオブジェクトの実行中にラムダオブジェクトが呼び出されただけの場合は、問題はありませんが、ラムダがの代わりに格納されている場合は、となり、ラムダで参照されたキャプチャされた変数)が実行されると、それ以上存在しない変数を参照します(未定義の動作)。
一般的なケースでは "上方へのfunarg"問題を解決するにはガベージコレクタが必要であり、C++にはガベージコレクタが必要です。あなたはいくつかのケースで行うことができます「の値によって」キャプチャされているので、ラムダは、独自のプライベートコピーを持っています
:あなたが捕獲さを変更したいがあれば
この場合
foo([counter]() mutable { counter++; })
はあなたにも必要なコピーmutable
というキーワードを使用するのは...キャプチャされたコピーを変更する場合はC++に必要とされるからです(キャプチャされたコピーはラムダの本体にあるconst
のオブジェクトです)。
残念ながら、キャプチャされた変数を2つのラムダ(たとえば、同じキャプチャされた変数に「インクリメンタ」と「デクリメンタ」の両方を作成するなど)で共有する必要がある場合、コピーの使用は実行できません。 これでできることは、値によってstd::shared_ptr
を変数に取り込むことです。ただし、単純なケースではガベージコレクタが正しく置き換えられます(ただし、参照ループの場合は使用されません)。
'関数が' someotherFunction'の中で実行されると、 'counter'は依然としてスコープ内にあるので、この関数は*働かなければなりません。しかし、 'someotherFunction'がラムダを*格納していて、後で' func'が返った後にラムダが実行されると、参照問題が発生します。 –
しかし、以下のコメントを見てみると、someotherFunctionの実行がfuncの実行を上回ると、それは正しく失敗するようです。 – sublime
ポイントは*内部* 'func'から' someotherFunction'を呼び出していることです。つまり、 'func'よりも長くはできません。 –