首先,我对C ++ 11还是比较陌生的,所以如果我错过任何东西,请原谅我的疏忽。所以我要做的是基本上调用函数传递函数和该函数的任意参数#,将其存储起来然后稍后异步调用它。似乎有两个主要选择:
问题是,是否比另一种更好?是否有利益/利弊/绩效优势?
谢谢!
编辑:根据要求,这里有一个澄清,第一种情况是更早期的绑定,我在调用者传递它们时将args绑定到函数,然后我存储绑定的函数以便稍后调用。第二种情况是我分别存储func和args,然后在必须调用时使用args调用函数。所以问题是哪个是更好的性能/代码/样式/等?答案 0 :(得分:1)
接受带有相应签名的std::function<...>
,稍后将其存储回调。让调用者决定他们更喜欢创建/填充参数。如,
#include <functional>
#include <iostream>
std::function<int(int)> stored_f;
void set_callback(std::function<int(int)> f) {
stored_f = std::move(f);
}
void run_the_callback(int value) {
std::cout << stored_f(value) << '\n';
}
int f(int i) {
return i + 1;
}
int g(int a, int b) {
return a + b;
}
int main() {
// Plain old function pointer
set_callback(f);
run_the_callback(1);
// Use std::bind
set_callback(std::bind(g, 2, std::placeholders::_1));
run_the_callback(2);
// Use a lambda
set_callback([](int i){ return f(i) * g(i, i);});
run_the_callback(3);
}
最佳性能 - 如果您不绝对需要对回调进行类型擦除 - 将在functor类型上参数化您的代码。 E.g:
#include <functional>
#include <iostream>
template <typename Functor>
void do_stuff_and_callback_sometimes(Functor f) {
std::cout << f(1) << '\n';
// do some stuff, then
std::cout << f(2) << '\n';
// more work, and finally
std::cout << f(3) << "\n\n";
}
int f(int i) {
return i + 1;
}
int g(int a, int b) {
return a + b;
}
int main() {
// Plain old function pointer
do_stuff_and_callback_sometimes(f);
// Use std::bind
do_stuff_and_callback_sometimes(std::bind(g, 2, std::placeholders::_1));
// Use a lambda
do_stuff_and_callback_sometimes([](int i){ return f(i) * g(i, i);});
}
在某些情况下避免类型擦除是不可能的,而在其他情况下则需要你跳过箍。是否值得这样做是情境化的。
答案 1 :(得分:0)
第三种可能性是将所有参数绑定到调用者的责任,并且只保留带有您要调用的签名的std :: function。
例如:
struct Silly
{
using Callback = std::function<void()>;
void registerCallback(Callback cb) { callback_ = std::move(cb); }
Callback callback_;
};
这种方式很明显,调用者有责任处理参数的生命周期,值与参考语义等。