ラムダでthis
(オブジェクトプロパティを変更する)をキャプチャする正しい方法は次のとおりです。
auto f = [this] () { /* ... */ };
しかし、私は私が見た次の特異性について興味があります:
class C {
public:
void foo() {
// auto f = [] () { // this not captured
auto f = [&] () { // why does this work?
// auto f = [&this] () { // Expected ',' before 'this'
// auto f = [this] () { // works as expected
x = 5;
};
f();
}
private:
int x;
};
私が混乱している(そして答えたい)奇妙な点は、次のように動作する理由です。
auto f = [&] () { /* ... */ }; // capture everything by reference
そして、なぜthis
を参照によって明示的にキャプチャできないのか:
auto f = [&this] () { /* ... */ }; // a compiler error as seen above.
[&this]
が機能しない理由は、構文エラーであるためです。 lambda-introducer
の各コンマ区切りパラメーターはcapture
です:
capture:
identifier
& identifier
this
&this
が構文的に許可されていないことがわかります。許可されない理由は、小さなconstポインターであるため、参照によってthis
をキャプチャしたくないためです。値で渡すだけです。したがって、言語は参照によるthis
のキャプチャをサポートしていません。
this
を明示的にキャプチャするには、[this]
をlambda-introducer
として使用できます。
最初のcapture
はcapture-default
にすることができます。
capture-default:
&
=
つまり、使用するものはすべて、参照(&
)または値(=
)によって自動的にキャプチャされます-ただし、this
の処理は特別です-どちらの場合も、値によってキャプチャされます以前に与えられた理由(&
のデフォルトキャプチャでも、通常は参照によるキャプチャを意味します)。
5.1.2.7/8:
名前ルックアップ(3.4)の目的で、
this
(9.3.2)のタイプと値を決定し、(*this)
(9.3を使用して、非静的クラスメンバーを参照するID式をクラスメンバーアクセス式に変換します。 .1)、複合文[OF THE LAMBDA]はラムダ式のコンテキストで考慮されます。
したがって、ラムダは、メンバー名を使用する場合(例では名前x
の使用)を囲むメンバー関数の一部であるかのように動作するため、this
の「暗黙の使用」を生成しますメンバー関数のように。
ラムダキャプチャに
&
であるcapture-defaultが含まれる場合、ラムダキャプチャの識別子の前に&
を付けてはなりません。ラムダキャプチャに=
であるcapture-defaultが含まれる場合、ラムダキャプチャにはthis
が含まれてはならず、含まれる各識別子の前には&
が付きます。識別子またはthis
は、ラムダキャプチャに複数回出現してはなりません。
したがって、[this]
、[&]
、[=]
、または[&,this]
をlambda-introducer
として使用して、this
ポインターを値でキャプチャできます。
ただし、[&this]
および[=, this]
は不正な形式です。最後のケースでは、gccはエラーではなく[=,this]
に対してexplicit by-copy capture of ‘this’ redundant with by-copy capture default
を許します。
標準には、キャプチャリストに&this
がないためです。
N4713 8.4.5.2キャプチャ:
lambda-capture:
capture-default
capture-list
capture-default, capture-list
capture-default:
&
=
capture-list:
capture...opt
capture-list, capture...opt
capture:
simple-capture
init-capture
simple-capture:
identifier
&identifier
this
* this
init-capture:
identifier initializer
&identifier initializer
ラムダキャプチャの目的で、式は潜在的に次のようにローカルエンティティを参照します。
7.3 this式は潜在的に* thisを参照します。
そのため、標準ではthis
および*this
が有効で、&this
が無効であることを保証しています。また、this
のキャプチャーは、*this
(これは左辺値、オブジェクト自体)のキャプチャーを意味します参照による、ではなくのキャプチャーthis
ポインター値による!