- remove if
- bind1st,bind2nd
- bind(普通,成员)
- copy
- 引用折叠
- 函数指针/指针函数
- 回调函数-延迟调用的思想
- 占位符
- function
- function+lambda
- 对象+回调函数对象
- bind+function+mem fn
- std::cref占位遍历
01_bind.cc
#include <iostream>
#include <functional>
using std::cout;
using std::endl;
using std::bind;
using std::function;
int add0(int a,int b){
cout<<"add(0)(int int )"<<endl;
return a+b;
}
int add1(int a,int b,int c){
cout<<"add(1)(int int int)"<<endl;
return a+b+c;
}
class Exemple{
public:
int add2(int a,int b){
cout<<"Exemple::add(2)(int int )"<<endl;
return a+b;
}
int _data=100;
};
void test(){
//函数的形态(类型,标签):函数的返回类型+参数列表
//(参数的个数,顺序,类型)
//add0:int (int,int)
//f0:int()
auto f0=bind(&add0,1,2);
cout<<f0()<<endl<<endl;
//----------//
//引用折叠
//& &&--> &
//& & --> &
//&& & -> &
//&& &&-> &&
//add1:int (int,int,int)
//f1:int()
auto f1=bind(add1,3,4,6);
cout<<f1()<<endl<<endl;
//add2:int (Exemple*,int,int)
//f2:int()
Exemple ex;
auto f2=bind(&Exemple::add2,&ex,10,20);
cout<<f2()<<endl<<endl;
/* Exemple::add2(10,20); */
//成员函数有隐藏参数this指针
auto f4=bind(&Exemple::add2,ex,10,20);
cout<<f4()<<endl<<endl;
//如果ex已经销毁,&ex就会对空指针进行解引用
//传对象则没有影响(copy了一份副本,生命周期和bind一致)
//传地址(一个地址的开销) 传对象(一个对象的开销)
//占位符
//add1:int (int,int,int)
//f5: int(int)
using namespace std::placeholders;
auto f5=bind(add1,100,_1,20);
cout<<f5(400,500,500)<<endl<<endl;
/* f1=bind(add1,100,_1,20); */
function<int()> f3=bind(&Exemple::_data,&ex);
cout<<f3()<<endl<<endl;
//数据成员(将数据成员的名字看成函数名字
//数据成员的类型看成函数的返回类型
}
void func(int a1,int a2,int a3,const int &a4,int a5){
cout<<"a1--"<<a1
<<"\ta2--"<<a2
<<"\ta3--"<<a3
<<"\ta4--"<<a4
<<"\ta5--"<<a5<<endl;
}
void test1(){
//占位符整体,代表的函数的形参位置
//占位符种的数字,代表的是实参的位置
//std::cref=const reference,引用的包装器
int num=100;
using namespace std::placeholders;
auto f=bind(func,10,_1,_2,std::cref(num),num);
//100->a4,a5
//默认的传递方式是值传递
num=200;
f(1,20,300,4000,5000);
//a1--10 a2--1 a3--20 a4--100 a5--100
//10->a1 1/_1->a2 20/_2->a3,剩下的扔掉
f(800,200);
}
int main(void)
{
test();
test1();
return 0;
}
02_funcPoint.cc
#include <iostream>
using std::cout;
using std::endl;
int func1(){
return 10;
}
int func2(){
return 20;
}
int add0(int a,int b){
cout<<"add(0)(int int )"<<endl;
return a+b;
}
//指针函数,函数的返回类型是指针
//int* re_arr(){
// reuturn int*=new int[5]();
//}
//<深入理解C指针>
void test(){
typedef int (*pFunc1)();//函数指针
//C写法
/* typedef int(*)() pfunc;//error */
using pfunc=int(*)();//取别名的另一种方式
//C++写法
//回调函数--将函数作为参数传递(延迟调用的思想??不懂)
pFunc1 f=func1;//注册回调函数
pfunc f1=func1;
cout<<f()<<endl;//回调函数的执行
cout<<f1()<<endl;
f=func2;
f1=func2;
cout<<f()<<endl;
cout<<f1()<<endl;
/* f=add; */
//函数形态不一致
}
int main(void)
{
test();
return 0;
}
03_lambda.cc
#include <iostream>
#include <functional>
#include <vector>
#include <string>
using std::cout;
using std::endl;
using std::vector;
using std::string;
using std::function;
void test(){
int num=10;
int age=20;
//fuction,类模板,封装一切可以调用的对象
//普通/成员函数,函数对象,lambda表达式
//lambda 的函数形态:void(int)
function<void(int)> f=[&age,num](int value){
/* auto f=[&age,num](int value){ */
++age;
++value;
cout<<"age--"<<age<<"\tnum--"
<<num<<"\tvalue--"<<value<<endl;
};
f(100);
f(200);
}
vector<function<void(const string &)>> vec;
void test1(){
int num=100;
string name("xixi");
/* function<void(const string &)> f= */
/* [&num,&name](const string & val)->void{ */
/* cout<<num<<"--"<<name<<"--"<<val<<endl; */
/* }; */
//return type可以省略
/* vec.push_back([&num,&name](const string &val){ */
vec.push_back([num,name](const string &val){
cout<<num<<"--"<<name<<"--"<<val<<endl;
});
//捕获局部变量的引用,药保证其不被销毁
for(auto ele:vec){
ele("wuhan");
}
}
void test2(){
for(auto ele:vec){
ele("wuhan");
}
}
int main(void)
{
test();
test1();
test2();
return 0;
}
04_bind1st_bind2nd.cc
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
using std::cout;
using std::endl;
using std::bind;
using std::vector;
template <typename Container>
void display( Container & con){
for(auto &ele: con){
cout<<ele<<" ";
}
cout<<endl;
}
void test(){
vector<int> vec{1,5,3,6,2,7,23,3,6};
display(vec);
//delete all val>4
auto it=remove_if(vec.begin(),vec.end(),[](int & value)->bool{
return value>4;
});
display(vec);
//pread pwrite 满足一元谓词->删除,read++
//不满足,swap *pread & *pwrite,pread++,return ++pwrite
vec.erase(it,vec.end());
display(vec);
}
void test1(){
vector<int> vec{1,5,3,6,2,7,23,3,6};
display(vec);
//less(val1,val2){return val1<val2;}
/* auto it=remove_if(vec.begin(),vec.end(), */
/* bind1st(std::less<int>(),4)); */
auto it=remove_if(vec.begin(),vec.end(),
bind2nd(std::greater<int>(),4));
display(vec);
vec.erase(it,vec.end());
display(vec);
}
int main(void)
{
test();
test1();
return 0;
}
05_bind_figure.cc
#include <iostream>
#include <functional>
#include <math.h>
using std::cout;
using std::endl;
using std::bind;
using std::function;
//面向对象:继承+虚函数(纯虚函数)
//基于对象:std::bind+std::function(更加灵活
//
//总结:在C语言中,解决回调函数的注册与执行 --> 函数指针
//C++:std::bind + std::function
//-------------------------------------------------//
class Figure
{
public:
//纯虚函数
/* virtual void display() const = 0; */
/* virtual double area() const = 0; */
using DisplayCallBack=function<void()>;
using AreaCallBack=function<double()>;
//bind(``````)是右值
/* void setDisplayC(const DisplayCallBack & dc){ */
//函数注册到成员函数
void setDisplayC(const DisplayCallBack && dc){
_display_callback=std::move(dc);
}
void setArea(const AreaCallBack && dc){
_area_callback=std::move(dc);
}
//执行注册的函数
void handleDisplayC()const{
if(_display_callback){
_display_callback();
}//nullptr
}
double handleAreaC()const{
if(_area_callback){
return _area_callback();
}
return 0.0;
}
public:
DisplayCallBack _display_callback;
AreaCallBack _area_callback;
};
//-------------------------------------------------//
class Rectangle
: public Figure
{
public:
Rectangle(double length = 0, double width = 0)
: _length(length)
, _width(width){
cout << "Rectangle(double = 0, double = 0)" << endl;
}
void displsy_r(int val) const {
cout << "Rectangle";
}
double area_r() const {
return _length * _width;
}
~Rectangle(){}
private:
double _length;
double _width;
};
//-------------------------------------------------//
class Circle
: public Figure
{
public:
Circle(double radius = 0)
: _radius(radius){
cout << "Circle(double = 0)" << endl;
}
void display_c() const {
cout << "Circle";
}
double area_c() const {
return 3.14 * _radius *_radius;;
}
~Circle(){}
private:
double _radius;
};
//-------------------------------------------------//
class Triangle
: public Figure
{
public:
Triangle(double a = 0, double b = 0, double c = 0)
: _a(a)
, _b(b)
, _c(c){
cout << "Triangle(double = 0, double = 0, double = 0)" << endl;
}
void display_t() const {
cout << "Triangle";
}
double area_t() const {
//海伦公式
double tmp = (_a + _b + _c)/2;
return sqrt(tmp * (tmp - _a) * (tmp - _b) * (tmp - _c));
}
~Triangle(){}
private:
double _a;
double _b;
double _c;
};
//-------------------------------------------------//
//-------------------------------------------------//
/* void func(const Figure &fig){ */
/* fig.display(); */
/* cout << "的面积 : " << fig.area() << endl; */
/* } */
void func(const Figure &fig){
fig.handleDisplayC();
cout<<"area: "<<fig.handleAreaC()<<endl;
}
//-------------------------------------------------//
//-------------------------------------------------//
void test(){
Rectangle r(10, 20);
Circle c(10);
Circle c1;
Triangle t(3, 4, 5);
cout<<endl;
Figure fig;
/* &bind(&Rectangle::displsy_r(),&r,10); */
fig.setDisplayC(bind(&Rectangle::displsy_r,&r,10));
fig.setArea(bind(&Rectangle::area_r,&r));
func(fig);
fig.setDisplayC(bind(&Circle::display_c,&c));
fig.setArea(bind(&Circle::area_c,&c));
func(fig);
fig.setDisplayC(bind(&Circle::display_c,&c1));
fig.setArea(bind(&Circle::area_c,&c1));
func(fig);
fig.setDisplayC(bind(&Triangle::display_t,&t));
fig.setArea(bind(&Triangle::area_t,&t));
func(fig);
}
int main(void)
{
test();
return 0;
}
06_mem_fn.cc
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using std::cout;
using std::endl;
using std::for_each;
using std::mem_fn;
using std::ostream;
using std::vector;
using std::function;
class Number
{
public:
Number(size_t data=0)
:_data(data)
{}
~Number(){}
bool isEven()const{
return _data%2==0;
}
bool isPrime()const{
if(_data==1){
return false;//1不是素数
}
for(size_t i=2;i<=_data/2;++i){
if(_data%i==0){return false;}
}
return true;
}
void print(){
cout<<_data<<" ";
}
friend ostream & operator<<(ostream & os,const Number & n);
private:
size_t _data;
};
ostream & operator<<(ostream & os,const Number & n){
os<<n._data<<" ";
return os;
}
void test(){
vector<Number> vec;
for(size_t i=1;i!=30;++i){
vec.push_back(Number(i));
}
//mem_fn用于将成员函数指针封装成一个函数对象
//使得可以像普通函数一样调用
/* for_each(vec.begin(),vec.end(),mem_fn(&Number::operator=)); */
for_each(vec.begin(),vec.end(),mem_fn(&Number::print));
cout<<endl;
//删除偶数
auto it=remove_if(vec.begin(),vec.end(),mem_fn(&Number::isEven));
vec.erase(it,vec.end());
for_each(vec.begin(),vec.end(),mem_fn(&Number::print));
cout<<endl;
//删除质数
it=remove_if(vec.begin(),vec.end(),mem_fn(&Number::isPrime));
vec.erase(it,vec.end());
for_each(vec.begin(),vec.end(),mem_fn(&Number::print));
cout<<endl;
//--------------------------------------------------//
Number n(10);
for_each(vec.begin(),vec.end(),std::bind(&Number::print,&n));
/* for_each(vec.begin(),vec.end(),std::bind(&Number::print,n)); */
cout<<endl;
using namespace std::placeholders;
/* function<void(Number)> f=bind(&Number::print,_1); */
//成员函数,类型不正确??
function<void(Number&)> f=bind(&Number::print,_1);
/* 创建一个 std::function<void(Number&)> 对象 f,它将
* Number 类的iprint 成员函数与占位符 _1 绑。 */
/* 这里 _1 表示在 for_each 中调用 f 时,将传递的每个元素
* 作为 print 的参数,即每个 Number 对象的引用。 */
for_each(vec.begin(),vec.end(),f);
cout<<endl;
for_each(vec.begin(),vec.end(),bind(&Number::print,_1));
cout<<endl;
}
int main(void)
{
test();
return 0;
}
作业:
01 什么是回调函数,注册回调函数,执行回调函数?(掌握std::bind用法,非常重要)
std::bind的实现原理阅读材料
http://www.cnblogs.com/xusd-null/p/3698969.html
01_bind.cc
02 std::bind可以绑定什么?bing绑定成员函数的传参有什么区别?
1,普通函数
2,成员函数(普通成员函数还需要传递函数对象,静态成员函数不需要
3,数据成员(名字看作函数名字,类型看作返回类型
4,lambda表达式
03 使用std::bind与std::function(基于对象的形式)实现上课所讲的Figure的例子的代码?
05_bind_figure.cc