[解決済み] ラムダで参照渡し('&this')を捕捉できないのはなぜですか?
質問
正しいキャプチャ方法は
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
は構文上許されないことがわかります。 なぜ許されないかというと、あなたは決して
this
は小さな定数ポインタなので、参照で捕捉することはできません。 値で渡したいだけなのです。ですから、この言語は
this
を参照で捕捉することをサポートしていません。
捕捉するために
this
を明示的に捕捉するには
[this]
として
lambda-introducer
.
最初の
capture
は
capture-default
というものである。
capture-default:
&
=
これは、何を使っても自動的にキャプチャされることを意味し、参照によって (
&
) または値によって (
=
) それぞれで、しかし
this
の扱いは特別で、どちらの場合も前に述べた理由で値で捕捉されます (デフォルトの捕捉が
&
であっても、通常は参照による捕捉を意味します)。
5.1.2.7/8:
名前検索(3.4)の目的のために,型と値を決定して
this
(9.3.2) の型と値を決定し、非静的なクラス・メンバーを参照する id- を使用して、非静的クラスメンバを参照するクラスメンバアクセス式に変換します。(*this)
(9.3.1), 複合文[OF THE LAMBDA]は,ラムダ式の文脈で考慮される。
つまり、ラムダはメンバ名を使用するとき、囲むメンバ関数の一部であるかのように動作します(例では、名前
x
の暗黙の用法"を生成します。
this
を生成します。
ラムダキャプチャーがキャプチャーのデフォルトを含んでいる場合
&
である場合、ラムダ・キャプチャー内の識別子は の前に&
. ラムダキャプチャーにキャプチャーのデフォルトが含まれている場合、そのデフォルトは=
である場合、そのラムダキャプチャにはthis
を含まないものとし,含む各識別子の前に&
. 識別子またはthis
は、ラムダ捕捉の中に複数回出現してはならない。 はラムダキャプチャーに複数回出現してはならない。
なので
[this]
,
[&]
,
[=]
または
[&,this]
として
lambda-introducer
を捕捉するために
this
のポインタを値で捕捉します。
しかし
[&this]
と
[=, this]
は不正な形式です。 最後の場合、gccは寛容に
[=,this]
に対して警告します。
explicit by-copy capture of ‘this’ redundant with by-copy capture default
というように、エラーではなく
関連
-
[解決済み] gdbを使用してもデバッグシンボルが見つからない
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 要素ごとの加算は、結合ループよりも分離ループの方がはるかに高速なのはなぜですか?
-
[解決済み] なぜC++はPythonよりもstdinからの行の読み込みが遅いのですか?
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] switch文の中で変数を宣言してはいけないのはなぜですか?
-
[解決済み] リスト内包とラムダ+フィルタの比較
-
[解決済み】C++11のラムダ式って何?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】coutはstdのメンバではない
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】#include<iostream>は存在するのですが、「識別子 "cout "は未定義です」というエラーが出ます。なぜですか?
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】Visual Studioのデバッガーエラー。プログラムを開始できません 指定されたファイルが見つかりません
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み】c++で.txtファイルから2次元の配列に読み込む