double divide(double x, double y) { return x / y; }
void test0()
{
//C++
function<double(double, double)> func1 = divide;
cout << func1(10, 2) << endl;
//C
double (*func2)(double, double) = divide;
cout << func2(12,3) << endl;
typedef double(*Func)(double,double);
Func func3 = divide;
cout << func3(15,5) << endl;
}
bind可以绑定函数中的参数再进行使用,比C语言中的更为方便。
同时需要注意:bind实质上是将函数入口进行了绑定
void test1()
{
using namespace placeholders;
function<double()> func1 = bind(divide, 10, 2);
cout << func1() << endl;
function<double(double)> func2 = bind(divide, _1, 2);
cout << func2(6) << endl;
function<double(double)> func3 = bind(divide, 6, _1);
cout << func3(1) << endl;
function<double(double, double)> func4 = bind(divide, _1, _2);
cout << func4(4, 2) << endl;
auto func5 = bind<int>(divide, 12.5, 3); //相当于 (int)divide(12.5, 3)
cout << func5() << endl;
}
首先要明白,直接将类中的成员函数赋值给函数指针是行不通的,因为成员函数中有隐含的this指针,是无法一并传给函数指针的。
如果是直接想绑定类中的成员函数的话:
1). 要么这个函数必须是static修饰(这样的话成员函数就不再拥有this指针,可以直接传递给函数指针,指针指向函数入口)
2). 要么在bind该函数的时候将this指针一同传入(也就是传入一个实例化的类对象就可以了)
class myclass
{
public:
double add(double x, double y)
{
return x + y;
}
};
void test2()
{
myclass my;
//传入my的作用在于传入隐含的this指针
function<double(double,double)> func1 = bind(&myclass::add, my, 2, 3);
cout << func1(1,2) << endl;
}
struct myStruct
{
double a, b;
double add()
{
return a + b;
}
};
//需要注意,func() 与 function<> 里面的参数个数,类型必须相同的,不能因为绑定了就少写
void test3(){
myStruct my{1,2};
//func1调用成员函数add
function<double()> func1 = bind(&myStruct::add, my);
cout << func1() << endl;
//此时的this指针是通过转递的方式, 而不是通过绑定的方式,反正只要传入this指针就行了,func2调用成员函数add
function<double(myStruct)> func2 = bind(&myStruct::add, placeholders::_1);
cout << func2(my) << endl;
//输出myStruct中的a, func3调用成员变量a
function<double(myStruct)> func3 = bind(&myStruct::a, my);
cout << func3(my) << endl;
}
ref可以理解为传入引用
cref 则是const reference
void f(int& n1, int& n2, const int& n3)
{
std::cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
++n1; // increments the copy of n1 stored in the function object
++n2; // increments the main()'s n2
// ++n3; // compile error
}
void test4()
{
int n1 = 1, n2 = 2, n3 = 3;
std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3));
n1 = 10;
n2 = 11;
n3 = 12;
std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
bound_f();
std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
}
Figure, Rectangle Circle 没有继承关系的类 实现多态
利用 bind 回调函数, Figure基类中注册回调函数,实现多态时再进行调用就可以了,本质上是属于bind注册回调函数。
#include
#include
#include
#include
#include
#include
#include
#define pi 3.1415926
using namespace std;
typedef function<void()> figureCallBack;
typedef function<double()> areaCallBack;
class Figure
{
public:
void setfigureFunc(figureCallBack cb1)
{
_cb1 = cb1;//注册回调函数
}
void setareaFunc(areaCallBack cb2)
{
_cb2 = cb2;//注册回调函数
}
void displayFigure()
{
_cb1();
}
double displayArea()
{
_cb2();
}
private:
figureCallBack _cb1;
areaCallBack _cb2;
};
class Rectangle
{
public:
Rectangle(int width, int length)
: _width(width), _length(length)
{
}
void displayFigure()
{
cout << "Rectangle" << endl;
}
double displayArea()
{
return _width * _length;
}
private:
int _width;
int _length;
};
class Circle{
public:
Circle(double radius)
:_radius(radius)
{
}
void displayFigure(){
cout << "Circle" << endl;
}
double displayArea(){
return pi * _radius * _radius;
}
private:
double _radius;
};
void display(Figure &f)
{
f.displayFigure();
cout << "Area = " << f.displayArea() << endl;
}
int main()
{
Rectangle rectangle(3, 4);
Circle circle(2);
Figure f;
//矩形
figureCallBack fn1 = bind(&Rectangle::displayFigure, &rectangle);
areaCallBack fn2 = bind(&Rectangle::displayArea, &rectangle);
f.setfigureFunc(fn1);
f.setareaFunc(fn2);
display(f);
//圆形
fn1 = bind(&Circle::displayFigure, circle);
fn2 = bind(&Circle::displayArea, circle);
f.setfigureFunc(fn1);
f.setareaFunc(fn2);
display(f);
return 0;
}
struct MyStruct
{
int val;
void print()
{
cout << "this is print" << endl;
}
void printval(int i)
{
cout << "this is printval " << i << endl;
}
};
void test1()
{
MyStruct my{10};
auto func1 = mem_fn(&MyStruct::print);
func1(my); //传入my是因为必须传入this指针
auto func2 = mem_fn(&MyStruct::printval);
func2(my, 2);
auto func3 = mem_fn(&MyStruct::val);
cout << func3(my) << endl;
}
class Data{
public:
Data(int data)
:_data(data)
{
}
void display(){
cout << _data << endl;
}
private:
int _data;
};
void test2(){
vector<Data> vec{Data(1), Data(2), Data(3)};
for_each(vec.begin(), vec.end(), mem_fn(&Data::display));//因为本身就是在Data类的内部,所以不再需要传入this指针
}
使用算法与函数结合的方法总结:
void display(int i)
{
cout << i << endl;
}
struct Mydisplay{
void display(int i ){
cout << i << endl;
}
bool operator()(int i){
cout << i << endl;
return true;
}
};
void test3()
{
vector<int> vec{1, 2, 3, 4, 5};
//1.使用Lambda表达式
// for_each(vec.begin(), vec.end(), [](int x){cout << x << endl;});
//2.使用普通函数
//for_each(vec.begin(), vec.end(), display);
//3.bind绑定普通函数
// for_each(vec.begin(), vec.end(), bind(display, 1));
//4.bind绑定类成员函数
// Mydisplay my;
// for_each(vec.begin(), vec.end(), bind(&Mydisplay::display, my, placeholders::_1));
//5.使用函数对象
// for_each(vec.begin(), vec.end(), Mydisplay());
}
#include
#include
struct 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()
{
// store a free function
std::function<void(int)> f_display = print_num;
f_display(-9);
// store a call to a member function
std::function<void(const Foo &, int)> f_add_display = &Foo::print_add;
const Foo foo(314159);
f_add_display(foo, 1);
// store a call to a function object
std::function<void(int)> f_display_obj = PrintNum();
f_display_obj(18);
// store the result of a call to std::bind
std::function<void()> f_display_31337 = std::bind(print_num, 31337);
f_display_31337();
// store a call to a member function and object
using std::placeholders::_1;
std::function<void(int)> f_add_display2 = std::bind(&Foo::print_add, foo, _1);
f_add_display2(2);
// store a call to a member function and object ptr
std::function<void(int)> f_add_display3 = std::bind(&Foo::print_add, &foo, _1);
f_add_display3(3);
}