これは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++ ;
};
}