C++ 怎么声明一个返回值为“按引用捕获参数的lambda”的函数

我承认标题很难读,而且不知道在这里提问合不合适。。。
但是还是希望好心人回答一下。 O(∩_∩)O 谢谢

声明一个返回不捕获参数的lambda的函数可以这样(在vs2012和gcc都可以编译通过):

#include 
 
int (*Test ()) (void)
{
    int x = 0;
    auto ret = ]() {
        return 123;
    };
    return ret;
}

int main()
{
    auto ans = Test();
    printf("%d\n", ans());
    return 0;
}


```


但是如果Test函数中的ret想要按引用捕获参数,Test函数应该怎么声明啊?我试了半天没通过。。
我的需求是让ret能改变Test中的x的值。就是closure。。
#include 
  
int (*Test ()) (void)//这个写法真是高大上
{
    int x = 0;
    auto ret = &]() {  //加个&就是按引用捕获参数了吧
        return 123;
    };
    return ret;
}
 
int main()
{
    auto ans = Test();
    printf("%d\n", ans());
    return 0;
}


```

你确定加个“&”能编译过么。。。:880:

我把Test函数也改成lambda
auto Test = ]() {
int i = 0;
auto ret = &]() {
i = i + 1;
return i;
};
return ret;
};
在vs2012编译不过,在gcc可以编译过,但是执行直接异常结束了。。。

lambda函数如果不用auto,实际上是这样的:
std::function<int(int)> func = ](int i){ return i;}
函数类型是不包含 … ]的内容的,只能规定参数与返回值,不能规定捕获方式和内容。

试试这个:
#include
typedef std::function<int()> Func;
Func Test(){
int i = 0;
return &](){ return i;} // 返回值随机,可能会crash
}
int main(){
return Test()();
}

嗯,确实。3楼的代码在gcc编译通过,多调用几次返回的lambda就得到随机值。这就说明C++不支持closure吧

折腾了一天,总结一下吧。
1、C++的lambda如果捕获一个函数的局部变量,在函数返回后变量会被释放的,所以做不到类似Lua那样的closure。
2、lambda就是没有固定类型的,不方便用std::function包装,但是也可以包装。
3、static变量不用捕获,所以可以把Test函数中的i改为static,但是也失去closure的意义了。
暂时想到这些了。。。

  1. lambda中所有的引用可以认为只是一个普通指针而已,而指针不会阻止对象释放。
  2. lambda中如果使用了引用传值,那么必须在外部保证该对象不会在lambda调用前释放到。
  3. 如果想要使用的对象是个实体或基本类型,可以按值传递进来,这样就不能在lambda中修改lambda外面的值。

c++中没有垃圾回收,所以不会存在lua中的闭包(阻止对象释放),如果非要阻止对象释放,可以使用自己实现类似cocos2d中的retain release机制。

1、C++的lambda如果捕获一个函数的局部变量,在函数返回后变量会被释放的,所以做不到类似Lua那样的closure。

C++函数局部变量就是会被释放的,lambda无法阻止释放,可以通过new出变量来传入智能指针。