/* stl::bind 使用 */
#include <iostream>
#include <string>
#include <functional>
/*
知识补充:
std::bind绑定器
将函数、成员函数和闭包转成function函数对象
将多元(n>1)函数转成一元函数或者(n-1)元函数。
bind()接受一个函数(或者函数对象,或者任何你可以通过"(...)"符号调用的事物),生成一个其有某一个或多个函数参数被“绑定”或重新组织的函数对象。
顾名思义,bind()函数的意义就像它的函数名一样,是用来绑定函数调用的某些参数的。
bind的返回值是可调用实体,可以直接赋给std::function对象
*/
/* 学生类 */
class Student
{
public:
//构造函数
Student(unsigned int id, const std::string &name) :_id(id), _name(name)
{
}
//析构函数
~Student()
{
}
public:
//调用
int test()
{
const std::string msg = "hello world .";
//绑定成员函数
auto func = std::bind(&Student::show, this, std::placeholders::_1);
//执行方法
func(msg);
return 0;
}
private:
//展示学生信息
void show(const std::string &msg)
{
printf(" student info : id [%u] , name [%s] , msg [%s] .\n", this->_id, this->_name.c_str(), msg.c_str());
}
private:
unsigned int _id;
std::string _name;
};
void test1()
{
/*
知识点1:
std::bind 绑定成员函数,并且将多元函数 转成 一元函数
*/
Student stu(12, "tom");
stu.test();
}
//全局函数
static void see(int i, char c, double d)
{
printf("===int[%d]====char[%c]===double[%lf]==\n", i, c, d);
}
void test2()
{
/*
知识点2:
std::bind 绑定全局函数,并且将多元函数 转成 一元函数
*/
//定义函数指针
void(*pFunc)(int, char, double) = see;
//绑定函数,并且部分赋值参数
auto b_func = std::bind(pFunc, std::placeholders::_1, 'c', 1.2);
b_func(10);
}
void test3()
{
/*
知识点3:
std::bind 调整参数顺序
*/
//定义函数指针
void(*pFunc)(int, char, double) = see;
//绑定函数,并且部分赋值参数
auto b_func = std::bind(pFunc, std::placeholders::_2, 'h', std::placeholders::_1);
/*
设计说明:
std::placeholders::_1 表示的是b_func的第一个参数
std::placeholders::_2 表示的是b_func的第二个参数
*/
b_func(1.4, 5);
}
int b_same(int x, int y)
{
printf("---b_same1--x[%d]---y[%d]------\n", x, y);
return 0;
}
void b_same(double x, double y)
{
printf("---b_same2--x[%lf]---y[%lf]------\n", x, y);
}
void test4()
{
/*
知识点4:
std::bind 绑定重载函数,需要显式地指定函数签名
*/
//绑定函数
std::function<void(double, double)> b_func = std::bind((void(*)(double, double))b_same, std::placeholders::_1, std::placeholders::_2);
/*
注意:
std::function 的模板参数是 函数签名,而非函数指针
*/
b_func(3.3, 4.4);
}
int main()
{
//printf("-----test1()-------\n");
//test1();
//printf("-----test2()-------\n");
//test2();
//printf("-----test3()-------\n");
//test3();
printf("-----test4()-------\n");
test4();
return 0;
}
/* std::function初始化注意点 */
#include <iostream>
#include <string>
#include <functional>
using namespace std;
typedef std::function<void(int)> TestCallback;
typedef void(*test_fn)(int);
void test()
{
//std::function 初始化方式一
TestCallback cb1 = NULL;
//std::function 初始化方式二
TestCallback cb2 = TestCallback();
if (cb1)
{
printf("-----Callback1 not empty .------\n");
}
if (cb2)
{
printf("-----Callback2 not empty .------\n");
}
//std::function 错误初始化 强调 cb3如果不初始化,值将是不确定
TestCallback cb3;
test_fn fn = NULL;
cb3 = std::bind(fn, std::placeholders::_1);
if (cb3)
{
/*
说明:
此时 cb3 实际上并没有方法实体,但是 if (cb3) 判断却是不为空,如果调用 cb3() 就会导致程序崩溃
因此在使用std::bind()方法之前一定要判断绑定的函数是否为 NULL
*/
printf("-----Callback3 not empty .------\n");
}
}
int main()
{
test();
getchar();
return 0;
}