我正在尝试返回一个 lambda 函数,该函数从其当前作用域中捕获一个变量。当我不捕获变量时,将返回 lambda 函数并且可以毫无问题地执行:
#include <iostream>
typedef void(*VoidLambda)();
VoidLambda get() {
VoidLambda vl = []() {
std::cout << "hello" << std::endl;
};
return vl;
};
int main()
{
get()(); //prints "hello" as expected
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果vl试图捕获一个变量,编译器将不再编译它:
#include <iostream>
typedef void(*VoidLambda)();
VoidLambda get(const char* x) {
VoidLambda vl = [x]() { //Error: no suitable conversion function from "lambda []void ()->void" to "VoidLambda" exists
std::cout << x << std::endl;
};
return vl;
};
int main()
{
get("hello")();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试将第二个 lambda 转换为 VoidLambda,但问题仍然存在。
我想知道第一个和第二个 lambda 表达式之间的区别是什么,以及如何解决这个问题(即返回带捕获的 lambda 函数)。
不捕获任何状态的 Lambda 函数是无状态的。因此,可以将它们建模为正常函数。如果他们需要捕获不再为真的状态:状态需要在某处并且函数指针没有状态的位置。
基本上有两种选择:
使用推导类型返回 lambda 函数,例如:
auto get(char* x) { return [x]{ std::cout << x << "\n"; }; }
Run Code Online (Sandbox Code Playgroud)返回 lambda 函数的类型擦除表示:
std::function<void()> get(char* x) { return [x]{ std::cout << x << "\n"; }; }
Run Code Online (Sandbox Code Playgroud)选择哪一种取决于您的需求。第二个在概念上更接近函数指针。第一个更有效,但需要该功能inline(或至少在使用时可见)。
| 归档时间: |
|
| 查看次数: |
145 次 |
| 最近记录: |