更新:下部の引用でコアチェアによって約束されたように、コードは不正な形式になりました:
場合識別子で単純キャプチャとして現れる宣言-IDのパラメータのラムダ宣言のパラメータ宣言句、プログラムが悪い形成されています。
少し前にラムダでの名前のルックアップに関していくつかの問題がありました。それらはN2927によって解決されました:
新しい表現は、キャプチャーされたエンティティーの使用を再マップするためにルックアップに依存しなくなりました。ラムダの複合ステートメントが2つのパスで処理される、またはその複合ステートメント内の名前がクロージャー型のメンバーに解決される可能性があるという解釈をより明確に否定します。
ルックアップは常にlambda-expressionのコンテキストで行われ、クロージャー型のメンバー関数本体への変換の「後」には決して行われません。[expr.prim.lambda] / 8を参照してください。
ラムダ式の化合物-文は生成機能・身体関数呼び出し演算子の([dcl.fct.def]を)が、名前検索の目的のために、[...]、化合物-文はの文脈で考えられていますラムダ式。[ 例:
struct S1 {
int x, y;
int operator()(int);
void f() {
[=]()->int {
return operator()(this->x+y); // equivalent to: S1::operator()(this->x+(*this).y)
// and this has type S1*
};
}
};
- 終了例 ]
(この例では、ルックアップが、生成されたクロージャタイプのキャプチャメンバーをどうにか考慮していないことも明らかにしています。)
名前foo
はキャプチャで(再)宣言されていません。ラムダ式を囲むブロックで宣言されます。パラメーターfoo
は、その外側のブロックにネストされているブロックで宣言されます(ラムダパラメーターについても明示的に言及している[basic.scope.block] / 2を参照)。ルックアップの順序は、明らかに内部ブロックから外部ブロックまでです。したがって、パラメータを選択する必要があります。つまり、Clangが正しいです。
キャプチャをinit-capture、つまりのfoo = ""
代わりにするfoo
場合、答えは明確ではありません。これは、キャプチャが「ブロック」が指定されていない宣言を実際に引き起こすためです。これについてコアチェアにメッセージを送った。
これは問題2211です(新しい問題のリストは間もなくopen-std.orgサイトに表示されますが、残念ながらいくつかの問題のプレースホルダーのみが表示されます。そのうちの1つはその1つです。Konaの前にそれらのギャップを埋めるために懸命に取り組んでいます月末の会議)。CWGはこれを1月の電話会議中に議論し、キャプチャ名がパラメーター名でもある場合、プログラムの形式を不正にするよう指示されています。