2013-10-13 18 views
8

私は現在C++ 11 lambdasで遊んでいて、理解できない例が見つかりました。標準によると:私はこのコードが原因で変数を取り込むのコンパイルされませんことを期待していたhttp://ideone.com/t9emu5ローカルではないラムダとキャプチャ変数 - "ブロックスコープ"とはどういう意味ですか?

:ideoneで

int a = 10; 
auto x = [a] { return 1;}; 
int main() { 
    int k = 5; 
    auto p = [k]{ return k; }; 
    return 0; 
} 

コード:

A lambda-expression whose smallest enclosing scope is a block scope (3.3.3) is a local lambda expression; any other lambda-expression shall not have a capture-list in its lambda-introducer

をので、私は簡単な例を作成しました非ブロックスコープ(または、少なくともauto x = ...の部分がブロックスコープ内にないと考える)。しかし、コードはコンパイル中です - それは大丈夫ですか?

これは問題ありません - ブロックの範囲は何ですか?

は(私は現在、私は唯一のideoneサイトへのアクセスを持っているので、私が使用しているものコンパイラバージョンはよく分からない。

感謝を説明するために!

それはこのようになります
+0

だから、どの範囲が非ブロックスコープですか? – matekm

+1

@DanielFrey Huh?ブロックは複合文であり、名前空間は確かにブロックではありません。 [basic.scope.block]/1と[stmt.block] – dyp

+0

@DyPを参照してください申し訳ありませんが、混乱しました。あなたは完全に正しいです! –

答えて

12

は、コンパイラの拡張機能です。G ++ 4.8を警告を与えながら0.1はこれをコンパイル:

error: 'a' cannot be captured because it does not have automatic storage duration

warning: capture of variable ‘a’ with non-automatic storage duration [enabled by default]

打ち鳴らす++ 3.4はこれをコンパイルできません

両方が[expr.prim.lambda]/10彼らがさらにラムダの囲みスコープをチェックしていないようだ

The identifiers in a capture-list are looked up using the usual rules for unqualified name lookup (3.4.1); each such lookup shall find a variable with automatic storage duration declared in the reaching scope of the local lambda expression.

を参照してください、私は変数のは名前がない(それは冗長になると想像することができます非ブロック/名前空間のスコープでの自動保存期間)。


ブロックスコープが[basic.scope.block]/1

A name declared in a block (6.3) is local to that block; it has block scope.

に定義され、ブロックは次のように定義されますので、あなたは右のあなたのことをしている

So that several statements can be used where one is expected, the compound statement (also, and equivalently, called “block”) is provided.

     compound-statement:
         {statement-seqopt}

グローバルに宣言されたラムダはブロックスコープ内でではなく、です。

+0

ありがとう! – matekm

+0

追加する:GCCはコンパイルフラグ '-pedantic-errors'(' -std = C++ 11'に加えて)を使って拒否させることができます( '-Wall -Wextra'も同様です)。 Ideoneでは、コンパイラオプションを指定することはできません。 [Coliru](http://coliru.stacked-crooked.com/)も([GCC Explorer](http://gcc.godbolt.org/))コンパイルするだけで(アセンブリの出力を表示します)、それはしませんリンクして実行しないでください)。 (もっとオンラインのC++コンパイラについては、例えば、http://isocpp.org/get-startedを参照してください。) –

+0

@gx_これは間違っているようです。私は '-Wall -Wextra -Wpedantic'でコンパイルし、' g ++ 'のバージョン5と6.1の間で、おそらく自分のコードでこのエラーについて話したことはありませんでした。 '-pedantic-errors'を追加することは、むしろ驚くことではありませんが、これを変更することはありません。 'g ++'は私に警告しません。私は2番目の意見をもっと頻繁に 'clang ++ 'に尋ねる必要があると思う –

関連する問題