我想知道是否可以在C ++ 11中编写一个返回lambda函数的函数。当然一个问题是如何声明这样的功能。每个lambda都有一个类型,但是这种类型在C ++中是不可表达的。我认为这不会起作用:
auto retFun() -> decltype ([](int x) -> int)
{
return [](int x) { return x; }
}
也不是这样:
int(int) retFun();
我不知道从lambdas到函数指针或类似指针的任何自动转换。手工制作函数对象并返回它的唯一解决方案是什么?
答案 0 :(得分:91)
您不需要手工制作的函数对象,只需使用std::function
,lambda函数可以转换为:
此示例返回整数标识函数:
std::function<int (int)> retFun() {
return [](int x) { return x; };
}
答案 1 :(得分:28)
对于这个简单示例,您不需要std::function
。
从标准§5.1.2/ 6:
没有 lambda-capture 的 lambda-expression 的闭包类型具有公共非虚拟非显式const转换函数,用于指向具有相同参数的函数并返回类型作为闭包类型的函数调用操作符。此转换函数返回的值应为函数的地址,该函数在调用时与调用闭包类型的函数调用操作符具有相同的效果。
因为你的函数没有捕获,这意味着lambda可以转换为指向int (*)(int)
类型函数的指针:
typedef int (*identity_t)(int); // works with gcc
identity_t retFun() {
return [](int x) { return x; };
}
这是我的理解,如果我错了,请纠正我。
答案 2 :(得分:18)
您可以从其他lambda函数返回lambda函数,因为您不应该显式指定lambda函数的返回类型。在全球范围内写下类似的内容:
auto retFun = []() {
return [](int x) {return x;};
};
答案 3 :(得分:14)
虽然这个问题专门询问了C ++ 11,但是为了其他偶然发现并且可以访问C ++ 14编译器的人,C ++ 14现在允许推导出普通函数的返回类型。因此,只需在函数参数列表后面删除-> decltype
...子句,就可以根据需要调整问题中的示例:
auto retFun()
{
return [](int x) { return x; }
}
但请注意,如果函数中出现多个return <lambda>;
,则无法使用此功能。这是因为对返回类型推导的限制是所有返回语句必须返回相同类型的表达式,但编译器为每个lambda对象赋予其自己的唯一类型,因此return <lambda>;
表达式将各自具有不同的类型
答案 4 :(得分:0)
您应该这样写:
auto returnFunction = [](int x){
return [&x](){
return x;
}();
};
以函数形式获得回报,并像这样使用它:
int val = returnFunction(someNumber);
答案 5 :(得分:0)
例如,如果您没有c ++ 11,并且正在微控制器上运行c ++代码。您可以返回空指针,然后执行强制转换。
void* functionThatReturnsLambda()
{
void(*someMethod)();
// your lambda
someMethod = []() {
// code of lambda
};
return someMethod;
}
int main(int argc, char* argv[])
{
void* myLambdaRaw = functionThatReturnsLambda();
// cast it
auto myLambda = (void(*)())myLambdaRaw;
// execute lambda
myLambda();
}