C++ 14の標準ドラフトN4140 5.1.2.12 [expr.prim.lambda]
の例はあまり理解できません。 ラムダのキャプチャされていない変数の使用
これは明示的にこれをキャプチャしない関連するキャプチャのデフォルトであり、自動保存期間を持つ変数です(initcaptureに関連付けられた非静的データを参照するために見つかったid式はすべて除外されます)。メンバーは)、(暗黙的実体をキャプチャすると言われている、すなわち、このまたは変数)化合物-if文:
- ODR-使用するエンティティ、または
- 名潜在的に評価された式どこでエンティティを包含式の完全表現は、lの到達範囲内で宣言された汎用ラムダパラメータに依存するambda-expression。
[例:
void f(int, const int (&)[2] = {}) { } // #1 void f(const int&, const int (&)[1]) { } // #2 void test() { const int x = 17; auto g = [](auto a) { f(x); // OK: calls #1, does not capture x }; auto g2 = [=](auto a) { int selector[sizeof(a) == 1 ? 1 : 2]{}; f(x, selector); // OK: is a dependent expression, so captures x }; }
末端例]
全てのこのような暗黙的に捕捉されたエンティティは、ラムダ式の到達範囲内で宣言されなければなりません。
[注:ネストされたラムダ式によるエンティティの暗黙的なキャプチャは、ラムダ式を含む暗黙のキャプチャを引き起こす可能性があります(下記参照)。これを暗黙的にodrで使用すると暗黙的に取得される可能性があります。末端ノート]
私は、そのため#1
呼び出しはエラー(撮影していない変数を使用してについて何か)につながるフレーズa lambda-expression with an associated capture-default
の始まりはどんな暗黙の捕獲を禁止するべきだと思った(そしてそれはコメントで確認しています)。それはどうやって動くの? f
の最初の議論は何でしょうか? test()
スコープを終了した後にg
が呼び出されるとどうなりますか? #1
の署名をvoid(const int&)
に変更するとどうなりますか?
更新:どのように動作するのか説明してくれてありがとうございます。後で、私はこの事件についての標準への参照を見つけて投稿しようとします。
'x'はconst式です。これはODRであり、参照のため#2だけに使用されます。 – Jarod42
つまり、 'g'はあたかも' {f(17);}のように振る舞います。 } '。 –