いくつかの用語:
=
または&
内部[&](){ /*..*/ }
は、 capture-default と呼ばれます。
- 変数の ODR 使用とは、変数が破棄値式 (
(void)some_variable
または などint x = some_variable, 5;
) に出現せず、定数式にも出現しないことを大まかに意味します。
- 複合ステートメントは「機能ブロック」
{
ステートメントです }
- 変数の名前はid-expressionです
[expr.prim.lambda]/3
ラムダ式の型(クロージャー オブジェクトの型でもあります) は、名前のない一意の非共用体クラス型 —クロージャー型と呼ばれます — のプロパティについては、以下で説明します。
/11
ラムダ式に関連付けられた capture-defaultとその複合ステートメントodr-uses (3.2)this
または自動保存期間を持つ変数があり、odr-used エンティティが明示的にキャプチャされていない場合、odr-used エンティティは暗黙的にキャプチャされます。
したがって、i
暗黙的にキャプチャされます。
/14
エンティティが暗黙的にキャプチャされ、capture-default が である=
場合、または を含まないキャプチャで明示的にキャプチャされた場合、エンティティはコピーによってキャプチャされます&
。コピーによってキャプチャされたエンティティごとに、名前のない非静的データ メンバーがクロージャー型で宣言されます。
int
クロージャー型に非静的データ メンバー (型) があります。
/17
コピーによってキャプチャされたエンティティの ODR 使用 (3.2) であるすべての id-expressionは、クロージャー型の対応する名前のないデータ メンバーへのアクセスに変換されます。
この段落はOPと非常によく似た例を提供するため、これを解釈する必要さえありません。
void f(const int*);
void g() {
const int N = 10;
[=] {
int arr[N]; // OK: not an odr-use, refers to automatic variable
f(&N); // OK: causes N to be captured; &N points to the
// corresponding member of the closure type
};
}
これを OP の例に適用すると、クロージャー型の内部の非静的データ メンバーを参照している&i
ことがわかります。診断メッセージが適切かどうかは、標準では指定されていません;)