【发布时间】:2012-09-20 07:30:56
【问题描述】:
这段代码对于 JS 开发者来说并不陌生
function get_counter()
{
return (
function() {
var c = 0;
return function() { return ++c; };
})();
}
它基本上创建了一个创建不同枚举数的。所以我想知道是否可以在 C++11 中使用新的 lambda 语义来完成同样的事情?我最终写了这段 C++ 不幸的是不能编译!
int main()
{
int c;
auto a = [](){
int c = 0;
return [&](){
cout << c++;
};
};
return 0;
}
所以我想知道是否有一种解决方法来编译它,以及编译器是否可以让这段代码正确运行?我的意思是它必须创建单独的枚举器,但它也应该收集垃圾(未使用的 c 变量)。
顺便说一句,我使用的是 VS2012 编译器,它会产生这个错误:
Error 2 error C2440: 'return' : cannot convert from 'main::<lambda_10d109c73135f5c106ecbfa8ff6f4b6b>::()::<lambda_019decbc8d6cd29488ffec96883efe2a>' to 'void (__cdecl *)(void)' c:\users\ali\documents\visual studio 2012\projects\test\test\main.cpp 25 1 Test
【问题讨论】:
-
@ecatmur vs2012 在这里我已经更新并添加了我收到的错误消息,除了你知道那段代码是否安全吗?我的意思是它是在浪费内存还是在某处实现了一些隐藏的垃圾收集器?
-
没有垃圾收集器,也不浪费内存。每次调用
a,都会返回一个新的 lambda 对象。您必须将a的返回值分配给某物——当该物被销毁时,lambda 用于捕获变量的任何资源都将随之销毁。 -
在 C++11 中,您需要一个
return expr;形式的主体来进行返回类型推导,而您没有。如果没有后 C++11 的扩展返回类型推导规则,此代码在任何情况下都不应该编译。如果 VS2012 有这些,我会感到惊讶。 -
@Xeo 事实上你是第一个(除了我;))意识到这一点。到目前为止,所有其他答案都集中在 by-ref 捕获上(这当然也是一个错误,但不是编译器错误)。
-
所以您的代码中有 2 个错误。一种是返回一个带有(可能)悬空引用的对象,另一种是不指定适当的返回类型(并导致编译器错误)。
标签: c++ visual-c++ lambda c++11 visual-studio-2012