2017-08-29 15 views
3

これは奇妙なことですが、静的変数をキャプチャできますが、変数がキャプチャリストに指定されていない場合、つまり暗黙的にキャプチャされます。ランバの静的変数をキャプチャできません

int main() 
{ 
    int captureMe = 0; 
    static int captureMe_static = 0; 

    auto lambda1 = [&]() { captureMe++; }; // Works, deduced capture 
    auto lambda2 = [&captureMe]() { captureMe++; }; // Works, explicit capture 
    auto lambda3 = [&]() { captureMe_static++; }; // Works, capturing static int implicitly 
    auto lambda4 = [&captureMe_static] { captureMe_static++; }; // Capturing static in explicitly: 
                   // Error: A variable with static storage duration 
                   // cannot be captured in a lambda 

    // Also says "identifier in capture must be a variable with automatic storage duration declared 
    // in the reaching scope of the lambda 

    lambda1(); lambda2(); lambda3(); // All work fine 

    return 0; 
} 

ノー、第3および第4のキャプチャが同等でなければなりません理解していませんよ?第三に、私は「自動記憶域期間」で変数をキャプチャしていないよ

編集:

auto lambda = [&] { captureMe_static++; }; // Ampersand says to capture any variables, but it doesn't need to capture anything so the ampersand is not doing anything 
auto lambda = [] { captureMe_static++; }; // As shown by this, the static doesn't need to be captured, and can't be captured according to the rules. 
+0

([C++ 11ラムダ参照により静的変数をキャプチャ]の可能な重複https://stackoverflow.com/questions/13827855/capturing-a-static-variable-by-reference-in "-a-c11-lambda) –

答えて

6

変数を持つ:私はこれに対する答えは、それはそう、静的変数をキャプチャすることはありませんということだと思います静的記憶期間はキャプチャする必要がないため、キャプチャできません。あなたは単にラムダ内でそれを使うことができます。

自動変数には問題があります:他の言語では、クロージャーは囲みスコープ内の変数への参照を単に格納しますが、ラムダには自動変数の存続期間を延長する機能がありません。それゆえ、ラムダにぶら下がっている参照を残して、範囲外に出る可能性があります。このため、C++では、コピーまたは参照によって自動変数をキャプチャするかどうかを選択できます。しかし変数が静的であれば、この問題は発生しません。ラムダはあたかもそれを参照によって捕捉したかのように単純に振る舞います。

で静的変数をキャプチャする場合は、C++ 14のinit-capture構文を使用します。

+0

"はキャプチャする必要がないため、キャプチャできません。 ここには論理がありません。 C++言語のルールにシームレスに適合する場合、なぜ明示的な静的変数取得を禁止するのですか? –

+0

@ sfk92fksdf私はあなたに言えませんでした。委員会の誰かが答えを知っているかもしれません。 – Brian

+1

@ sfk92fksdfお探しの答えがあります:https://stackoverflow.com/a/13828144/2865757 – Zefick

0

これはあなたが望むものではありませんか?

static int dont_capture_me = 0; 

auto foo = [] { dont_capture_me++; }; 

もちろん、参照は明示的に保存できますが、基本的には同等です。

auto bar = [&reference = dont_capture_me] { reference++; }; 
関連する問題