在 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;
}
我需要用什么来替换 type1/type2 才能使上述工作正常工作?希望您能看到我正在尝试完成的工作,因此即使通过直接替换 type1 和 type2 无法做到这一点,也许您可以指导我朝着正确的方向前进。
换句话说:
谢谢!
编辑:我正在使用 Visual Studio 2010 进行编译
最佳答案
你永远无法知道 lambda 函数的类型,因为逻辑上发生的是编译器生成一个(本地)类,函数调用运算符重载,词法闭包由该(本地)类的数据成员表示。这是 lambda 函数的逻辑情况,例如:
auto foo = [](int x, int y) { return x + y; };
编译器在逻辑上这样做:
struct CompilerGeneratedName { void operator()(int x, int y) const { return x + y; } };
CompilerGeneratedName foo;
由于编译器生成一个(本地)类,它生成一个名称,因此您永远不能显式编写类型,您只能从模板函数参数的类型推导或使用 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;};
}
我一直在逻辑上说的原因是因为这就是 boost::lambda 最初的工作方式(即使 C++03 不允许在模板函数参数中使用本地类)以及添加 lambda 函数的想法的起源from 但是由于这是一个语言特性,现在编译器供应商可以用不同的和更有效的方式实现它,比如通过引用捕获所有环境时,编译器可以只传递一个指向调用堆栈的指针而不是逻辑方式,同时仍然保持逻辑看法。
关于lambda - lambda 函数的类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3161219/