提问人:Nick Ruha 提问时间:11/23/2022 更新时间:11/23/2022 访问量:47
如何保存函数指针以供以后在 c++ 中使用,具有保存状态的类似闭包
How do I save a function pointer for later use in c++, similar closures that have a saved state
问:
我是一个 c++ 新手,所以我不确定如何写这个,但基本上我想要一个函数,它接受一些参数并返回一个不需要任何参数的函数指针,可以执行以供以后使用。就像一个闭合。
我知道 c++ 没有闭包,但可以通过 lambda expessions 获得一些相同的效果。我只是不确定它是否能做我想让它做的事情。同样,我对 c++ 了解不多。我一直在阅读有关 lambdas 如何在 c++ 中工作的文章和文章,但我不知道如何让这段代码工作。
这是我尝试在打字稿中执行的一些示例代码
let myVariable;
const myClosure = (param1: number, param2: number, param3, string, ) => {
return () => {
// Do something with params
console.log(param1, param2, param3);
}
}
function whereInitalized() {
myVariable = myClosure(1,2,"name");
}
function whereExecuted() {
myVariable(); // prints the params
}
whereInitalized();
whereExecuted();
这是我在 c++ 中想要的,但这是错误的
// Not correct syntax or type
// Having trouble getting typing for this variable;
std::function<void(param1: T, param2: P, param3: V)> (*myVariable)() = myClosure;
std::function<void()> myClosure(param1: T, param2: P, param3: V) {
return []() { // Returns a function that does not take a parameter
param1.someMethod();
param2->Call(blah, blah);
// ... More work
};
}
void functionWhereInitalized() {
myVariable = myClosure(param1, param2, param3);
}
void functionWhereExecuted() {
myVariable();
}
这是我在 c++ 中拥有的东西,有效,但不能接受参数
std::function<void()> myVariable = myClosure;
std::function<void()> myClosure() {
return [num = 99]() mutable {
// Test code to see it gets called
num++;
std::cout << num << " -- " << "\n";
};
}
void functionWhereInitalized() {
myVariable = myClosure();
}
void functionWhereExecuted() {
myVariable();
}
我感谢提前的任何回复!
答:
在回答技术问题之前,我同意 Sam Varshavchik 的一句话:
你说你“不太懂 c++”。不幸的是,您将了解C++的第一件事是它与即时满足无关。学习它需要时间,很长一段时间。您正在描述 C++ 库中的基本模板之一,但要达到目的,有必要学习和学习核心 C++ 基础知识大约一两年,然后才能达到其高级主题,如模板。任何试图缩短这一过程的尝试最终都会以眼泪告终。C++太复杂了,不能通过在Stackoverflow上一次问一个问题来学习。
现在是技术问题:您可以使用 lambda 捕获1 实现简单的闭包,如下所述:
#include <iostream>
#include <string_view>
auto make_closure(std::ostream& out, std::string_view message, int repeat=1)
{
return [&out,repeat,message]() mutable { while (repeat --> 0) out << message; };
}
int main(){
auto say_hello = make_closure(std::cout, "Hello\n", 2);
say_hello();
}
1)
捕获是以逗号分隔的零个或多个捕获列表,可以选择以 capture-default 开头。捕获列表定义可从 lambda 函数体中访问的外部变量。唯一的捕获默认值是
&
(通过引用隐式捕获使用的自动变量)和(通过复制隐式捕获使用的自动变量)。 如果存在任一捕获默认值,则可以隐式捕获当前对象 ()。如果隐式捕获,则始终通过引用捕获它,即使捕获默认值为 。不推荐使用捕获默认值的隐式捕获。(从 C++ 20 开始)=
*this
=
*this
=
评论
std::function<void(param1: T, param2: P, param3: V)> (*myVariable)() = myClosure;
我不确定这里发生了什么。我的疯狂猜测是你想做这样的事情
std::function<void()> yourClosure(T1 const& p1, T2 const& p2, T3 const& p3)
{
return [p1, p2, p3]() { /* do the thing */};
}
但是,如果您只想存储函数以供以后使用,您实际上可以
auto const function = [a,b,c](){ /* meaningful code*/ };
或
some_types... a, b, c; // whatever variables you have
auto const function_with_params = [](auto const& a, auto const& b, auto const&c){ /* skrnyr dgdyr */};
auto const function_with_bound_params = std::bind(function_with_params, a, b, c);
lambda 版本和绑定版本都应该可以强制转换为std::function<void()>
评论
=
[=]() {