[解決済み] ラムダキャプチャと同名のパラメータ - どちらがシャドウになるのか?(clang vs gcc)
質問
auto foo = "You're using g++!";
auto compiler_detector = [foo](auto foo) { std::puts(foo); };
compiler_detector("You're using clang++!");
-
clang++ 3.6.0 で、それ以降の出力は "あなたはclang++を使用しています!" という警告が表示され キャプチャ
foo
は未使用です。 -
g++ 4.9.0 で、より新しいプリントアウト "あなたはg++を使用しています!" と警告し パラメータ
foo
は未使用です。
ここで、どのコンパイラがより正確にC++標準に準拠しているのでしょうか?
どのように解決するのですか?
更新:一番下の引用文にあるCore chairの約束通り、そのコードは が不正な形式になっています。 :
もし 識別子 の中に シンプルキャプチャー のように表示されます。 宣言者ID のパラメータとして表示されます。 ラムダ宣言子 's パラメータ宣言節 であるため、プログラムは不正確な形式です。
しばらく前に、ラムダでの名前検索に関するいくつかの問題がありました。それらは N2927 :
新しい文言では、捕捉された実体の用途を再マップするためにルックアップに依存しなくなりました。 より明確に という解釈を否定しています。 複合ステートメント が2回で処理される、あるいはその 複合ステートメント の名前がクロージャ型のメンバに解決されるかもしれません。
ルックアップは常に ラムダ式 のコンテキストで行われ、決してクロージャ型のメンバ関数本体への変換の後では行われません。参照 [expr.prim.lambda]/8を参照してください。 :
は ラムダ式 's 複合ステートメント は 関数本体 ([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* }; } };
- 終了例 ]
(この例では、lookupがクロージャ型の生成されたキャプチャメンバを何らかの形で考慮しないことも明確にしています)。
名前
foo
はキャプチャーの中で(再)宣言されるのではなく、ラムダ式を囲むブロックの中で宣言されます。パラメータ
foo
はその外側のブロックにネストされたブロックの中で宣言されます (
[基本.スコープ.ブロック]/2
も明示的にラムダパラメータについて言及しています)。ルックアップの順序は明らかに
内側から外側のブロックへ
. したがって、パラメータは選択されるべきであり、つまり、Clangは正しいのです。
もし、キャプチャをinit-captureにするとしたら、つまり
foo = ""
の代わりに
foo
の代わりに
これは課題 2211 です (新しい課題リストがまもなく open-std.org サイトに表示されますが、残念ながら多くの課題に対するプレースホルダーがあるだけで、これはそのうちのひとつです; 私は月末のコナ会議までにこれらのギャップを埋めるために懸命に働いています)。CWGは、1月の電話会議でこれについて議論しました。 は、キャプチャ名がパラメータ名でもある場合、プログラムを不正な形式にするよう指示しています。
関連
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み] 型名の後の括弧は、newで違いがあるのでしょうか?
-
[解決済み] g++とgccの違いは何ですか?
-
[解決済み] クロージャ」と「ラムダ」の違いは何ですか?
-
[解決済み] C++の規格では、初期化されていないboolがプログラムをクラッシュさせることは可能ですか?
-
[解決済み] LINQとLambdaでJoin/Whereを実現する
-
[解決済み] g++でC++11をコンパイルする
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
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++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】C++でユーザー入力を待つ【重複あり
-
[解決済み】C++ 式はポインタからオブジェクトへの型を持っている必要があります。
-
[解決済み】C++プログラムでのコンソールの一時停止
-
[解決済み] 非静的データメンバの無効な使用
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み] [Solved] インクルードファイルが開けません。'stdio.h' - Visual Studio Community 2017 - C++ Error
-
[解決済み】1つ以上の多重定義されたシンボルが見つかる
-
[解決済み】演算子のオーバーロード C++; <<操作のパラメータが多すぎる
-
[解決済み] スタックアロケーションにより初期化されていない値が作成された