房屋信息网站,兼职做页面的网站,宁波做网站烟台厂商,wordpress被cc回调函数
回调函数的创建步骤大概为#xff1a;
声明一个函数指针类型。拟写使用回调函数的函数#xff0c;将函数指针类型及变量名声明作为参数传递。拟写符合函数指针类型的实现函数#xff0c;将实现函数的指针作为参数传递给使用它的函数。
定义回调函数的指针类型
声明一个函数指针类型。拟写使用回调函数的函数将函数指针类型及变量名声明作为参数传递。拟写符合函数指针类型的实现函数将实现函数的指针作为参数传递给使用它的函数。
定义回调函数的指针类型包括返回值类型、(*类型名)函数指针、参数表
typedef int (*Calc)(int a, int b);回调函数的使用者函数
int CalcValue(int a, int b, const Calc func) {return func(a, b);
}符合函数指针类型的实现函数
int Add(int a, int b) {return a b;
}实现函数的类型必须要和函数指针的类型声明一致也就是返回值和参数表个数、类型要完全一致。
typedef int (*Calc)(int a, int b);
int CalcValue(int a, int b, const Calc func) {return func(a, b);
}
int Add(int a, int b) {return a b;
}
int main()
{int a 4;int b 6;int c CalcValue(a, b, Add);std::cout c: c std::endl;return 0;
}std::function
可调用对象
一个函数指针一个具有operator()成员函数的类对象(传说中的仿函数)lambda表达式一个可被转换为函数指针的类对象一个类成员(函数)指针bind表达式或其它函数对象
std::function 是一个模板类。作用是对C中的可调用对象进行包装例如普通函数、成员函数、模板函数、静态函数、lambda表达式等。可以把std::function看做一个函数对象用于表示函数这个抽象概念。std::function的实例可以存储、复制和调用任何可调用对象存储的可调用对象称为std::function的目标若std::function不含目标则称它为空调用空的std::function的目标会抛出std::bad_function_call异常。
最基本的作用是简化调用的复杂程度统一调用的方式。如果代码中混杂着大量普通函数、模板函数、lambda使用 std::function 是比较适合的。
std::functionreturnType(argType, argType...) func;模板类当中对类型的声明方式是 返回值类型 ( 参数类型1, 参数类型2, …)
使用场景
绑定一个函数普通函数或者静态函数实现回调函数作为函数入参
std::functionvoid(int) f; // 这里表示function的对象f的参数是int返回值是void
#include functional
#include iostreamstruct Foo {Foo(int num) : num_(num) {}void print_add(int i) const { std::cout num_ i \n; }int num_;
};void print_num(int i) { std::cout i \n; }struct PrintNum {void operator()(int i) const { std::cout i \n; }
};int main() {// 存储自由函数std::functionvoid(int) f_display print_num;f_display(-9);// 存储 lambdastd::functionvoid() f_display_42 []() { print_num(42); };f_display_42();// 存储到 std::bind 调用的结果std::functionvoid() f_display_31337 std::bind(print_num, 31337);f_display_31337();// 存储到成员函数的调用std::functionvoid(const Foo, int) f_add_display Foo::print_add;const Foo foo(314159);f_add_display(foo, 1);f_add_display(314159, 1);// 存储到数据成员访问器的调用std::functionint(Foo const) f_num Foo::num_;std::cout num_: f_num(foo) \n;// 存储到成员函数及对象的调用using std::placeholders::_1;std::functionvoid(int) f_add_display2 std::bind(Foo::print_add, foo, _1);f_add_display2(2);// 存储到成员函数和对象指针的调用std::functionvoid(int) f_add_display3 std::bind(Foo::print_add, foo, _1);f_add_display3(3);// 存储到函数对象的调用std::functionvoid(int) f_display_obj PrintNum();f_display_obj(18);
}#include functional
class A
{std::functionvoid() callback_;
public:A(const std::functionvoid() f) :callback_(f) {};void notify(void){callback_();}
};
class Foo {
public:void operator()(void){std::cout __FUNCTION__ std::endl;}
};
int main(void)
{Foo foo;A aa(foo);aa.notify();
}#include functional
void call_when_even(int x, const std::functionvoid(int) f)
{if (!(x 1)){f(x);}
}
void output(int x)
{std::cout x ;
}
int main(void)
{for (int i 0; i 10; i){call_when_even(i, output);}std::cout std::endl;
}std::bind
是一个基于模板的函数作用是绑定并返回一个 std::function 对象。 那么什么是“绑定”它本身作为延迟计算的思想的一种实现作为一个调用过程当中的转发者而存在返回一个 std::function 对象。 它与 std::function 不同的是function 是模板类bind 是模板函数而 bind 返回的可调用对象可以直接给 function 进行包装并保存。
为什么要进行“包装”与“转发”呢 首先不规范的解释是function 的作用是包装它可以包装类成员函数但却无法生成类成员函数的可调用对象。而 std::bind 则是可以生成。 因此function 与 bind 结合后便成为了 C 中类成员函数作为回调函数的一种规范的实现方式。
std::bind(funcName, std::placeholders::_1, ...);当用作普通函数的绑定时第一个参数是可调用对象(普通函数、lambda等)而第二个参数开始对应可调用对象的参数表。 std::placeholders::_1 代表可调用对象的第一个参数_2就代表第二个参数依此类推。
当用作类成员函数的绑定时第一个参数仍然是作为类成员的可调用对象引用第二个参数则是对象的指针而第三个参数开始对应可调用对象的参数表。同样使用 std::placeholders::_* 依次向后推。
因为类成员函数都有一个默认的参数this作为第一个参数这就导致了类成员函数不能直接赋值给std::function需要std::bind简言之std::bind的作用就是转换函数签名将缺少的参数补上将多了的参数去掉甚至还可以交换原来函数参数的位置。
注意
调用指向非静态成员函数指针或指向非静态数据成员指针时首参数必须是引用或指针可以包含智能指针如 std::shared_ptr 与std::unique_ptr指向将访问其成员的对象。到 bind 的参数被复制或移动而且决不按引用传递除非包装于 std::ref 或 std::cref 。允许同一 bind 表达式中的多重占位符例如多个 _1 但结果仅若对应参数 u1 是左值或不可移动右值才良好定义。
class Baseclass
{
public:int Add(int a, int b) { return a b; };
};
int main()
{int a 1;int b 2;std::shared_ptrBaseclass ptr_class std::make_sharedBaseclass();std::functionint(int, int) addFunc std::bind(Baseclass::Add, ptr_class, std::placeholders::_1, std::placeholders::_2);int c addFunc(a, b);std::cout c: c std::endl;return 0;
}参考 c 回调函数与std::function使用实例