2015-12-22 8 views
6

パラメータを含む5つのローカル変数を持つローカル関数内で、たとえばstd::find_ifを実行する場合があります。しかし、ラムダは、STLアルゴリズムに渡すと、そのうちの1つにのみアクセスする必要があります。私は、次のいずれかの方法でこれをキャプチャすることができます:暗黙のキャプチャよりもラムダで明示的にキャプチャすることを好むのはいつですか?

私にできること
void foo(int one, int two, int three) 
{ 
    std::vector<int> m_numbers; 
    int four, five; 

    std::find_if(m_numbers.begin(), m_numbers.end(), [=](int number) { 
     return number == four; 
    }); 
} 

または:

void foo(int one, int two, int three) 
{ 
    std::vector<int> m_numbers; 
    int four, five; 

    std::find_if(m_numbers.begin(), m_numbers.end(), [four](int number) { 
     return number == four; 
    }); 
} 

(構文エラーまたは他の過ちについて謝罪、私はこのコードをコンパイルしていないに注意してください)

私は暗黙のキャプチャがodr-usedのルールに基づいていることを知っています。したがって、機能的にも実装上も、私はどちらも同じだと思います。暗黙のキャプチャより明示的なキャプチャをいつ使用しますか?私の唯一の考えは、カプセル化の原則に多少関連しています。必要なものだけにアクセスできるようにすると、コンパイラは変数にアクセスしたときに判断するのを手助けすることができます。また、メソッドのローカル状態を保持します(実行中の関数の存続期間は不変です)。しかし、本当に実用的な懸念はありますか?

明示的なキャプチャを暗黙のキャプチャよりも使用する理由はありますか?フォローする親指またはベストプラクティスの良いルールは何ですか?

+2

IIRCへの参照をダングリング取得することは危険ですそれを使用し、それを保持しません。もちろん、さまざまなシナリオで暗黙のキャプチャを使用するときに陥る可能性のあるトラップの例があります。 – chris

+0

このようなトラップの例は非常に高く評価されます。これらの例は、相違点を比較し、良い一般的な練習規則を確立するのに役立ちます。 –

+6

@chris Scott Meyersさんのお勧めは別の方法です。効果的な現代C++、アイテム31:デフォルトのキャプチャモードを避けます。 – LogicStuff

答えて

2
  • 明示的なキャプチャは常に好ましいです。あなたのラムダは、可変キャプチャの範囲外です。 &で、スコット・マイヤーズはかなりだけでは関数の引数です。このような場合に暗黙のキャプチャを使用するために(彼の最新の著書に)示唆ローカル破壊変数
2

[=]または[&]という名前を付けずに、実行時に最も簡単で最も効率的です。

this answerで説明されているように、変数はodr-usedの場合にのみ取得されます。つまり、コンパイラは必要なものだけをキャプチャします。あなたがキャプチャリストを指定した場合

することは、2つの違いが発生する可能性があります:

  • あなたはラムダあなたは、ラムダが必要としなかった何かをキャプチャ
  • を使用して何かをキャプチャするのを忘れ。

2番目のケースでは、値で取り込むと、オブジェクトが不必要にコピーされることを意味します。

私の助言は、具体的な理由以外の理由があると思わない限り、[][&]、または[=]です。そのようなケースの1つは、一部の変数を参照で、一部を値で取得する場合です。それはあまりエラーが発生しやすい

  • 重いものの場合に&を使用することをお勧めします(ない簡単なint型、ダブルなど)
  • 使用=あなたが使用することを計画しているよう

  • 関連する問題