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;
}

似乎我应该能够做到这一点,因为 c 在 make_function 返回后不再存在,但确实如此

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

我猜 [=] 是这样的,所以 c 的存储值和可变值允许修改存储的值,尽管我只是想确定一下。

Valgrind 完全没有抱怨这一点。每次我调用 make_counter 时,valgrind 都会报告一个额外的分配和空闲,所以我假设 lambda 元编程代码正在为变量插入内存的分配代码。我想知道这是否符合 Cxx11 或者它是否只是 g++ 特定的。

假设答案是正确的,我可以将 make_counter 简化为

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

1 回答 1

5

是的。

通过指定[=]您制作了局部变量的副本,并且该副本被隐藏在 lambda 中的某处。该表达式c++使用该本地副本,它将与 lambda 一样存在。

请注意,如果引用外部变量,mutable则没有必要;c它的存在是必要的,因为它c被复制捕获并因此存在于 lambda“主体”中。

于 2013-02-23T18:22:42.150 回答