Cam*_*Cam 8 lambda closures return-type anonymous-function c++11
在C++ 0x中,我想知道lambda函数的类型是什么.特别:
#include<iostream>
type1 foo(int x){
return [x](int y)->int{return x * y;};
}
int main(){
std::cout<<foo(3)(4);//would output 12
type2 bar = foo(5);
std::cout<<bar(6);//would output 30
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我需要更换type1/type2才能使上述功能正常工作?希望你能看到我想要完成的事情,所以即使直接替换type1和type2是不可能的,也许你可以引导我朝着正确的方向前进.
换一种说法:
谢谢!
编辑:我正在使用visual studio 2010进行编译
snk*_*kid 14
你永远不可能知道lambda函数的类型,因为逻辑上发生的是编译器生成一个(本地)类,函数调用运算符重载,词法闭包由该(本地)类的数据成员表示.这是lambda函数逻辑上发生的事情,例如:
auto foo = [](int x, int y) { return x + y; };
Run Code Online (Sandbox Code Playgroud)
编译器在逻辑上执行此操作:
struct CompilerGeneratedName { void operator()(int x, int y) const { return x + y; } };
CompilerGeneratedName foo;
Run Code Online (Sandbox Code Playgroud)
由于编译器生成一个(本地)类,它会生成一个名称,因此您永远不能显式写入该类型,您只能从模板函数参数的类型推导或使用auto/decltype中推断出类型.
此外,C++ 0x闭包是静态分配的,因此无论如何都无法安全地返回原始C++ 0x闭包.
仍然有几种方法可以实现这一点,第一种方法更灵活,并支持捕获词法范围的lambda函数.使用std :: function,如果你有一个lambda函数,它没有从外部作用域捕获任何东西,那么你可以使用函数指针,但这种转换更适合使用遗留代码而不是任何东西.
基本上你想要的是这个:
std::function< int (int) > foo(int x)
{
return [x](int y)->int{return x * y;};
}
Run Code Online (Sandbox Code Playgroud)
我一直在逻辑上说的原因是因为这是boost :: lambda最初的工作原理(即使C++ 03不允许在模板函数参数中使用本地类),并且添加lambda函数的想法来自于但是由于这是一种语言功能,现在编译器供应商可以以不同且更有效的方式实现它,例如通过引用捕获所有环境时,编译器可以只传递指向调用堆栈的指针而不是逻辑方式,同时仍保持逻辑视图.
来自维基百科:
Lambda函数是依赖于实现的类型的函数对象; 此类型的名称仅供编译器使用.如果用户希望采取一个lambda函数作为参数,类型必须是一个模板类型,或者必须创建一个
std::function
捕捉到λ值.
VC10编译了这个
//Beware, brain-compiled code ahead!
#include<iostream>
#include<functional>
std::function<int(int)> foo(int x)
{
return [x](int y)->int{return x * y;};
}
int main(){
std::cout<<foo(3)(4) << '\n';
auto bar = foo(5);
std::cout<<bar(6) << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
和打印
12 30