1、绑定普通函数
int add(int x , int y)
{
cout << "int add(int, int)" << endl;
return x + y;
}
void test()
{
//函数形态转变:int(int,int)-》int()
//f的类型就是int(),但是直接写int() f=std::bind(add, 1, 2);会报错
auto f = std::bind(add, 1, 2); //std::function f = std::bind(add, 1, 2);
cout << "f() = " << f() << endl; //调用bind绑定的add函数,函数实参是1和2
}
2、绑定成员函数
class Test
{
public:
int add(int x , int y)
{
cout << "int Test::add(int, int)" << endl;
return x + y;
}
int data = 135;//C++11新的方式初始化数据成员
};
Test tst;
//Test::add()总共有3个参数:this指针,x,y
std::function f2 = bind(&Test::add, &tst, 3, 4);
cout << "f() = " << f() << endl; //调用bind绑定的add函数,函数实参是1和2
Test tst;
tst.add();//编译器会翻译成:Test::add(&tst)
3、占位符
int add(int x , int y)
{
cout << "int add(int, int)" << endl;
return x + y;
}
void test()
{
//占位符:表示这里要传一个参数
std::function f4 = bind(add, 1, std::placeholders::_2);
//_2表示该占位符要传第2个实参:5_
cout << "f4(5) = " << f4(2,5,6) << endl;
//f4(2);报错,因为没有第2个实参
}
4、引用包装器
void func4(int x1, int x2, int x3, const int &x4, int x5)
{
cout << "x1 = " << x1
<< ", x2 = " << x2
<< ", x3 = " << x3
<< ", x4 = " << x4
<< ", x5 = " << x5 << endl;
}
void test()
{
int number = 100;
//这么写还是值传递
auto f = bind(func4, 1, std::placeholders::_9
, std::placeholders::_3, number, number);
number = 12345;//传递到func4()里的number还是100
//引用包装器cref = c = const ref = reference
auto f = bind(func4, 1, std::placeholders::_9
, std::placeholders::_3, std::cref(number), number);
//使用引用包装器把number变成引用
number = 12345;//传递到func4()里的number是12345
f(16, 27, 19, 200, 300, 500, 100, 200, 300);
}
5、绑定到数据成员
class Test
{
public:
int data = 135;//C++11新的方式初始化数据
};
Test tst;
std::function f5 = bind(&Test::data, &tst);//绑定到数据成员
cout << "f5() = " << f5() << endl;//f5() = 135
6、bind()实现多态
使用function+bind()代替纯虚函数+继承
#include
#include
using std::cout;
using std::endl;
using std::bind;
using std::function;
//function + bind可以取代纯虚函数 + 继承来实现多态
class Figure
{
public:
/* typedef function DisplayCallback;//C的写法 */
using DisplayCallback = function;
using AreaCallback = function;
DisplayCallback _displayCallback;
AreaCallback _areaCallback;
//注册回调函数
/* void setDisplayCallback(function &&cb) */
void setDisplayCallback(DisplayCallback &&cb)
{
_displayCallback = std::move(cb);
}
void setAreaCallback(AreaCallback &&cb) //引用折叠
{
_areaCallback = std::move(cb);
}
//执行回调函数
void handleDisplayCallback() const
{
if(_displayCallback)
{
_displayCallback();
}
}
double handleAreaCallback() const
{
if(_areaCallback)
{
return _areaCallback();
}
else
{
return 0;
}
}
};
class Circle
{
public:
Circle(double radius)
: _radius(radius){}
void display(int x) const
{
cout << "Circle";
}
double area() const
{
return 3.14159 * _radius * _radius;
}
private:
double _radius;
};
class Rectangle
{
public:
Rectangle(double length, double width)
: _length(length), _width(width){}
void show() const
{
cout << "Rectangle";
}
double showArea() const
{
return _length * _width;
}
private:
double _length;
double _width;
};
void func(Figure &fig)
{
fig.handleDisplayCallback();
cout << "'s area : " << fig.handleAreaCallback() << endl;
}
int main()
{
Circle circle(10);
Rectangle rectangle(10, 20);
Figure fig;
//std::function f = std::bind(&Circle::display, &circle, 10); */
/*fig.setDisplayCallback(std::move(f)); */
fig.setDisplayCallback(bind(&Circle::display, &circle, 10));
fig.setAreaCallback(bind(&Circle::area, &circle));
func(fig);
fig.setDisplayCallback(bind(&Rectangle::show, &rectangle));
fig.setAreaCallback(bind(&Rectangle::showArea, &rectangle));
func(fig);
return 0;
}
引用折叠:
template
func(T &&);
T &&
当T是以下类型时:
int ===》 int &&
int & ------------> int & && ----------> int &
int && ---------->int && && ----------> int &&
T &
当T是以下类型时:
int ===》 int &
int & ----------> int & & ----------> int &
int && ---------->int & && ----------> int &
function
_displayCallback; _displayCallback = std::move(cb);
等号右边取右值的原因:
对_displayCallback对象赋值时,调用 function类的移动赋值运算符函数,可以减少资源的消耗