C++ 保留一份将来要做的工作清单
由于函数指针需要提前知道提供了哪些参数,我不知道如何做到这一点 基本上我想要一份工作清单。每个条目都是一个要使用特定参数调用的函数。也就是说,我想在工作列表中添加C++ 保留一份将来要做的工作清单,c++,c++11,C++,C++11,由于函数指针需要提前知道提供了哪些参数,我不知道如何做到这一点 基本上我想要一份工作清单。每个条目都是一个要使用特定参数调用的函数。也就是说,我想在工作列表中添加foo(3,“abcd”),然后再添加bar(&h)。也就是说,我事先不知道会添加什么类型的函数 稍后我将迭代这个列表并执行指定的函数调用 这可以实现吗?您正在寻找的,或者是lambdas,或者 std::function是任意可调用函数的包装器。您可以在其中存储任何可以使用适当参数调用operator()的内容 可以存储在其中的一件事
foo(3,“abcd”)
,然后再添加bar(&h)
。也就是说,我事先不知道会添加什么类型的函数
稍后我将迭代这个列表并执行指定的函数调用
这可以实现吗?您正在寻找的,或者是lambdas,或者
std::function
是任意可调用函数的包装器。您可以在其中存储任何可以使用适当参数调用operator()
的内容
可以存储在其中的一件事是lambda:将调用和参数封装到非参数lambda中并调用它
您可以存储的另一个内容是std::bind
的结果std::bind实际上是一个元函数:它接受函数f和参数作为输入,并返回一个函数对象,其调用导致对参数调用f
以下是您如何将此应用于您的案例。常见设置:
std::vector<std::function<void()>> workList;
fillWorkList(workList);
for (auto& f : workList)
f();
还有一个是lambdas:
void fillWorkList(std::vector<std::function<void()>>& workList)
{
workList.push_back([]() { foo(3, "abcd"); });
workList.push_back([]() { bar(&h); });
}
void fillWorkList(标准::向量和工作列表)
{
workList.push_back([](){foo(3,“abcd”);});
workList.push_back([](){bar(&h);});
}
这里有一个解决方案,允许使用add(foo,3,“abcd”)
:
#include <functional>
#include <string>
#include <iostream>
#include <vector>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Worklist {
public:
template <typename ...Args>
void add(Args&&... args) {
worklist.push_back(std::bind(std::forward<Args>(args)...));
}
void do_all()
{
for(auto& i : worklist) {
i();
}
}
std::vector<std::function<void(void)>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add(foo, 3, "abcd");
worklist.add(bar,&h);
worklist.do_all();
}
#包括
#包括
#包括
#包括
#包括
void foo(int val,std::string text){std::coutAstd::function
表示可以调用的内容,但不返回任何内容
最清晰的东西是一只羔羊
std::function<void()> f = []{ foo(3, "abcd"); };
这会将h
复制到lambda中,然后使用指向h
的指针调用bar
。有时您希望h
是可变的:
std::function<void()> g = [h]()mutable{ bar(&h); };
然后std::function f=custom{“abcd”};
是另一种表示您将使用3调用foo
,std::string(“abcd”)
调用f()
的方式,当您在f
上使用std::bind
或std::function>时,可以编写一个将lambda作为任务的类
这里,使用std::unique_ptr
存储每个lambda:
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Generic_Callable {
public:
~Generic_Callable() = default;
virtual void call() = 0;
};
template <typename T>
class MyCallable : public Generic_Callable {
public:
MyCallable(T &&t) : ptr{std::make_unique<T>(std::move(t))} {}
void call() override
{
(*ptr)();
}
std::unique_ptr<T> ptr;
};
class Worklist {
public:
template <typename T>
void add(T &&t)
{
worklist.push_back(std::make_unique<MyCallable<T>>(std::move(t)));
}
void do_all() {
for(auto& i : worklist)
i->call();
}
std::vector<std::unique_ptr<Generic_Callable>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add([]() {foo(3, "abcd"); });
worklist.add([&h]() {bar(&h); });
worklist.do_all();
}
#包括
#包括
#包括
#包括
#包括
void foo(int val,std::string text){std::cout如何指定foo(3,“abcd”)或bar(&h)作为函数的参数?即具有任意参数的任意函数。@JensJensen编译器将假定您正在传递返回值。即,它将对表达式求值。您需要使用绑定或将其包装在lambda中,以便将可调用对象作为参数传递。@JensJensen这就是答案所显示的。从mstd::bind
,或将其包装在lambda中。您能澄清您不理解的内容吗?lambda是否必须捕获h
?因此,您能调用函数add_work(foo,3,'abcd')并将参数指定为std::bind binding吗?
std::function<void()> g = [h]()mutable{ bar(&h); };
struct custom {
std::string s;
void operator()() const {
foo( 3, s );
}
};
#include <string>
#include <iostream>
#include <vector>
#include <memory>
#include <utility>
void foo(int val, std::string text) { std::cout << val << '\t' << text << '\n'; }
void bar(int* ptr) { std::cout << *ptr << '\n'; }
class Generic_Callable {
public:
~Generic_Callable() = default;
virtual void call() = 0;
};
template <typename T>
class MyCallable : public Generic_Callable {
public:
MyCallable(T &&t) : ptr{std::make_unique<T>(std::move(t))} {}
void call() override
{
(*ptr)();
}
std::unique_ptr<T> ptr;
};
class Worklist {
public:
template <typename T>
void add(T &&t)
{
worklist.push_back(std::make_unique<MyCallable<T>>(std::move(t)));
}
void do_all() {
for(auto& i : worklist)
i->call();
}
std::vector<std::unique_ptr<Generic_Callable>> worklist;
};
int main()
{
int h{9};
Worklist worklist;
worklist.add([]() {foo(3, "abcd"); });
worklist.add([&h]() {bar(&h); });
worklist.do_all();
}