3

これはg++4.7で動作します

#include <iostream>
#include <functional>                                                                           

std::function<int()> make_counter() {
    return []()->std::function<int()> {
        int c=0;
        return [=]() mutable ->int {
            return  c++ ;
        };  
    }();
}   


int main(int argc, char * argv[]) {
    auto count1= make_counter();
    auto count2= make_counter();

    std::cout << "count1=" << count1() << std::endl;
    std::cout << "count1=" << count1() << std::endl;
    std::cout << "count2=" << count2() << std::endl;
    std::cout << "count1=" << count1() << std::endl;
    std::cout << "count2=" << count2() << std::endl;
    return 0;
}

make_functionが戻った後、cはもう存在しないので、これを実行できるはずですが、実際には存在します。

count1=0
count1=1
count1=2
count2=0
count1=3
count2=1

[=]は、cの値が保存され、変更可能であるため、保存された値を変更できるようになると思いますが、確認したいだけです。

Valgrindはこれについてまったく文句を言いません。make_counterを呼び出すたびに、valgrindは追加の割り当てと解放を報告するため、ラムダメタプログラミングコードが変数のメモリの割り当てコードを挿入していると想定します。これがCxx11に準拠しているのか、それともg++固有のものなのか疑問に思います。

答えが正しければ、make_counterを次のように簡略化できます。

std::function<int()> make_counter() {                                                             
      int c=0 ;
      return [=]() mutable ->int {
          return  c++ ;
      };  
}
4

1 に答える 1

5

はい、そうです。

ローカル変数のコピー[=]を作成したことを指定すると、そのコピーはラムダのどこかに隠されます。式はそのローカルコピーを使用します。これはラムダが使用する限り存続します。c++

外部変数を参照しmutableていれば、は必要なかったことに注意してください。cその存在はc、コピーによってキャプチャされ、ラムダの「ボディ」内に存在するという事実によって必要になります。

于 2013-02-23T18:22:42.150 に答える