从lambda的内部框架修改via闭包中的变量是否安全,该lambda是从不再存在函数的函数创建的

AC.*_*AC. 3 c++ c++11

这适用于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;
}
Run Code Online (Sandbox Code Playgroud)

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

count1=0
count1=1
count1=2
count2=0
count1=3
count2=1
Run Code Online (Sandbox Code Playgroud)

我猜测[=]使得所以c存储和可变的值的值允许修改存储的值虽然我只是想确定.

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

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

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

Mat*_* M. 5

是的.

通过指定[=]您创建了局部变量的副本,并且该副本存储在lambda中的某个位置.表达式c++使用的是本地副本,只要lambda就可以使用.

请注意,引用外部变量时mutable没有必要c; c通过复制捕获的事实使其存在是必要的,因此生活在lambda"体内".