2017-04-02 8 views
2

以下のコードではキャプチャモードを指定していませんが、some_staticはクロージャ内で表示されます。だから問題は、それが実際にキャプチャされているのか、あるいは何とか他の方法で参照されているのかどうかということです。ラムダはローカル静的変数をどのようにキャプチャしますか?

ボーナス問題は、コンパイラがこのようなラムダをクロージャではなくフリー関数にすることができるかどうかです。これはキャプチャリストが指定されていないため可能です。

std::vector<std::function<bool(int)>> filters; 

int main() 
{ 
    static int some_static = 1; 
    filters.emplace_back([](int){ 
     return some_static == 2; 
    }); 
} 
+0

あなたが何を求めているのかは分かりません。あなたはすでに何が起こったのか観察しました。どうしたの? –

+0

静的変数は取得できません。 – cpplearner

答えて

6

グローバル変数またはstatic変数をキャプチャする必要はありません。自動変数だけを使用したい場合は、キャプチャする必要があります。

そのため、そういうラムダを関数ポインタに変換できます。任意捕捉で


Cppreference:

識別子(このキャプチャ以外の)初期化せずにラムダの到達範囲内の通常の非修飾名ルックアップを使用して参照されます。参照の結果は、到達範囲で宣言された自動保存期間がの変数でなければなりません。ラムダオブジェクト自体に変数にコピーまたは参照を置くための手段を「捕捉する」

(強調鉱山)

グローバル変数およびstatic変数は、固定メモリロケーションを持っています。コンパイル時にその場所がわかっていて、変更されないので、それらを使用するためにコピーまたは参照を格納する必要はありません。

(あなたが本当にグローバルまたはstatic変数のコピーを持っているしたい場合、あなたはラムダオブジェクトにカスタムメンバ変数を作成することができますC++ 14からという名前のキャプチャを使用して作成することができます。しかし、あなただけではグローバル/ static変数を使用したい場合は、このようなキャプチャが必要ではありません。)

自動変数が、一方で、が固定位置を持っていません。全く同じ場所に作成された複数のラムダは異なるの自動変数を参照することができます。そのため、ラムダオブジェクトは、のような変数をキャプチャする必要があります。これは、使用される自動変数への参照またはそのコピーを含むことを意味します。

1

一般に、ラムダは、変数と単一のメンバ関数(舞台裏で)を持つクラスとして実装されます。しかし、静的なコードを取得する場合、コードはコンパイラによって生成されるため、スコープ規則はなく、静的に直接アクセスすることもできます。したがって、静的変数だけをキャプチャするラムダは、空のクラスメンバリストを持ち、単純な関数ポインタに最適化されている可能性があります。

関連する問題