メンバー関数内にラムダ関数を記述するときに、囲んでいるクラスのフィールドを値でキャプチャする方法はありますか? デフォルトのキャッチオール=
は機能しません。ラムダ内の変数を参照すると、代わりにキャプチャされた this ポインターから逆参照が行われ、キャプチャ リストで変数に明示的に名前が付けられるためですcapture of non-variable <name>
。‘this’ was not captured for this lambda function
3 に答える
いいえ、データメンバーを値でキャプチャすることはできません。ラムダは2種類のものしかキャプチャできません。
this
ポインタ、および- 非静的ローカル変数(つまり、自動保存期間を持つ変数)。
コメントでildjarnが指摘しているように、データメンバーの値のコピーを使用してローカル変数を作成し、そのローカル変数を値でキャプチャできます。
データメンバーの明示的な値によるキャプチャが許可されている場合、明示的なキャプチャの動作は暗黙的なキャプチャの動作とは異なるため、混乱を招く可能性があると私は主張します。たとえば、int
という名前のタイプのアクセス可能なデータメンバーが与えられた場合m
、次のように異なる結果が生成されるのは奇妙なことです。
[=] () mutable { m = 1; } // we modify this->m
[=m]() mutable { m = 1; } // we modify the copy of m that was captured
はい、単に[<new name>=<your class field>]
構成を記述します。例えば:
class MyClass {
int a;
void foo() {
auto my_lambda = [a_by_val=a] {
// do something with a_by_val
}
my_lambda();
}
}
C++ はスピードの言語であり、言語の設計において最も重要なことの 1 つはパフォーマンスです。標準的な設計者がクラスのすべての変数を値でキャプチャする方法を実装したい場合は、非常に巨大なクラスを考えて、それらすべてを値でキャプチャしますか? 関数で宣言されたすべての変数(を含む)をキャプチャする場合でも、this
2つの方法があります:
値による: 関数で定義された変数はスタックに残されるため、数メガバイトになることはありませんが、ヒープを使用するクラス
vector
は依然として巨大になる可能性があります。なので、気をつけて使ってくださいね!参照: 実際にスタック ポインターを保存します。
したがって、値を持つクラスのすべての変数を効率的にキャプチャする方法はありませんが、関数内でそのクラスのローカル コピーを作成し、参照によってキャプチャすることはできます。