6 C++ Boost 函数对象 目录: 关于bind bind2nd程序 bind与bind2nd,效果一样 bind1st 减法 bind1st 与bind 做减法 bind2nd调用仿函数 bind 不需要ptr_fun适配 std:bind2nd 与 boost:bind 当参数大于2个,std::bind已经没办法了,boost::bind限10个 bind_api[图] bind用于函数 以及 函数指针 bind用于函数对象 bind用于函数对象,(用引用避免函数对象的拷贝) bind 函数成员指针 bind 嵌套 关于mem_fun[图] boost.function 包装类的成员函数 function与functionN[图] 使用function对象的引用的示例[图] boost.lambda介绍 lambda出场 lambda相关的文件[图] lambda的占位符[图] 占位符总是传元素的引用. lambda操作符表达式01.png lambda操作符表达式02.png lambda操作符表达式03.png lambda操作符表达式04.png lambda操作符表达式05.png 延迟常量.png 延迟常量实例,
函数对象.png
关于bind.png
bind2nd程序
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
int a[]={1,2,3,4,5,6};
transform(a,a+6,a,bind2nd(plus<int>(),10));
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
11 12 13 14 15 16
pi@raspberrypi:~/boost $
bind与bind2nd,效果一样
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/bind.hpp>
using namespace std;
int main()
{
int a[]={1,2,3,4,5,6};
transform(a,a+6,a,bind2nd(plus<int>(),10));
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
transform(a,a+6,a,boost::bind(plus<int>(),_1, 100));//_1占位符
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
11 12 13 14 15 16
111 112 113 114 115 116
pi@raspberrypi:~/boost $
bind1st 减法
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/bind.hpp>
using namespace std;
int main()
{
int a[]={1,2,3,4,5,6};
transform(a,a+6,a,bind1st(minus<int>(),50));//bind第1个参数,50去减每一个
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
49 48 47 46 45 44
pi@raspberrypi:~/boost $
bind1st 与bind 做减法
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/bind.hpp>
using namespace std;
int main()
{
int a[]={1,2,3,4,5,6};
transform(a,a+6,a,boost::bind(minus<int>(),100,_1));//_1占位符
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
99 98 97 96 95 94
pi@raspberrypi:~/boost $
bind2nd调用仿函数
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/bind.hpp>
using namespace std;
int fun(int a,int b)
{
return a+b;
}
int main()
{
int a[]={1,2,3,4,5,6};
transform(a,a+6,a,bind2nd(ptr_fun(fun),50));//将一个普通的函数适配成一个仿函数
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
51 52 53 54 55 56
pi@raspberrypi:~/boost $
bind 不需要ptr_fun适配
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <algorithm>
#include <iterator>
#include <boost/bind.hpp>
using namespace std;
int fun(int a,int b)
{
return a+b;
}
int main()
{
int a[]={1,2,3,4,5,6};
transform(a,a+6,a,bind(fun,_1,50));//bind不需要提前做适配
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
51 52 53 54 55 56
pi@raspberrypi:~/boost $
std:bind2nd 与 boost:bind
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/bind.hpp>
using namespace std;
struct A
{
void f(int i) { cout << "A::A()" << i <<endl;}
};
void fun()
{
vector<A*> v;
v.push_back(new A);
v.push_back(new A);
v.push_back(new A);
v.push_back(new A);
int i = 5;
cout <<"std:bind2nd"<<endl;
for_each(v.begin(),v.end(),bind2nd(mem_fun(&A::f),i));
cout <<"boost:bind"<<endl;
for_each(v.begin(),v.end(),bind(&A::f,_1,i));//boost
}
int main()
{
fun();
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
std:bind2nd
A::A()5
A::A()5
A::A()5
A::A()5
boost:bind
A::A()5
A::A()5
A::A()5
A::A()5
pi@raspberrypi:~/boost $
当参数大于2个,std::bind已经没办法了,boost::bind限10个
pi@raspberrypi:~/boost $ cat main.cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <boost/bind.hpp>
using namespace std;
int f3(int a,int b,int c)
{
return a+b+c;
}
int main()
{
int a[]={1,2,3,4,5,6};
transform(a,a+6,a,bind(f3,_1,20,10));
copy(a,a+6,ostream_iterator<int> (cout," "));
cout << endl;
return 0;
}
pi@raspberrypi:~/boost $ g++ -Wall main.cpp &&./a.out
31 32 33 34 35 36
pi@raspberrypi:~/boost $
bind_api[图]
bind api (0个参数,1个参数)
解读:
bind实际就是一个函数
无参数的bind,需要一个函数对象
bind用于函数 以及 函数指针
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
using namespace std;
using namespace boost;
int f(int a,int b)
{
cout << "a="<<a<<" b="<<b<<endl;
return a+b;
}
int g(int a,int b,int c)
{
cout << "a="<<a<<" b="<<b<<" c="<<c<<endl;
return a+b+c;
}
int main()
{
bind(f,1,8);//返回无元函数对象,返回f(1,8)
bind(g,1,8,12);//同上
int x =10;
bind(f,_1,5)(x);//返回f(x,5);
bind2nd(ptr_fun(f),6)(x);//返回f(x,6);
bind(f,5,_1)(x); //返回f(5,x);
bind1st(ptr_fun(f),5)(x );//返回f(5,x);
bind(f,ref(x),_1)(29);//传参数的引用
bind(f,cref(42),_1)(28);//传const参数的引用
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
a=10 b=5
a=10 b=6
a=5 b=10
a=5 b=10
a=10 b=29
a=42 b=28
chunli@Linux:~/boost$
bind用于函数对象
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
using namespace std;
using namespace boost;
struct F
{
int operator()(int a,int b)
{
return a - b;
}
bool operator()(long a,long b)
{
return a == b;
}
};
int main()
{
F f;
int x = 108;
//由于函数对象F内部没有定义return_type类型
//所以下面需要显式的写成bind<int>
bind<int>(f,_1,_1)(x);
//由于函数对象less<>内部定义了return_type类型
//所以下面的bind不需要写成bind<int>
bind(less<int>(),_1,9)(x);
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
chunli@Linux:~/boost$
bind用于函数对象,(用引用避免函数对象的拷贝)
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
using namespace std;
using namespace boost;
struct F
{
int s;
typedef void result_type;
void operator()(int x)
{
s += x;
}
};
int main()
{
F f = {0};
int a[] = {1,2,3};
for_each(a,a+3,bind(ref(f),_1));//成功
//for_each(a,a+3,bind(f,_1)); //传函数对象的副本,失败
cout << f.s << endl;
assert(f.s == 6);
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
6
chunli@Linux:~/boost$
bind 函数成员指针
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
using namespace std;
using namespace boost;
struct X
{
bool f(int a)
{
cout <<"a="<<a<<endl;
return true;
}
};
int main()
{
X x;
shared_ptr<X> p(new X);
int i = 5;
bind(&X::f,ref(x),_1)(i);//x.f(i)
bind(&X::f,&x,_1)(i);//(&x)->f(i)
bind(&X::f,x,_1)(i);//(internal copy of x).f(i)
bind(&X::f,p,_1)(i);//(internal copy of x)->f(i)
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
a=5
a=5
a=5
a=5
chunli@Linux:~/boost$
bind 嵌套
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/bind/apply.hpp>
#include <boost/ref.hpp>
using namespace std;
using namespace boost;
void f1(int i)
{
cout << "f1() i="<<i<<endl;
}
void f2(int i)
{
cout << "f2() i="<<i<<endl;
}
int main()
{
std::vector< void (*)(int) > v;//函数指针类型
v.push_back(f1);
v.push_back(f1);
v.push_back(f2);
v.push_back(f2);
for_each(v.begin(),v.end(),bind(apply<void>(),_1,5));
//for_each(v.begin(),v.end(),bind(_1,5));//失败
//int k = 99;
//for_each(v.begin(),v.end(),bind(apply<void>(),_1,++k));//OK
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
f1() i=5
f1() i=5
f2() i=5
f2() i=5
chunli@Linux:~/boost$
关于mem_fun[图]
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>
#include <boost/bind/apply.hpp>
#include <boost/ref.hpp>
using namespace std;
using namespace boost;
struct X
{
void f()
{
cout << "Hello Boost!" << endl;
}
};
void g(vector<X> &v)//支持直接传对象
{
for_each(v.begin(),v.end(),boost::mem_fn(&X::f));
}
void h(vector<X*> &v)//支持对象指针
{
std::for_each(v.begin(),v.end(),boost::mem_fn(&X::f));
}
void k(vector<boost::shared_ptr<X> > const &v)//支持智能指针
{
std::for_each(v.begin(),v.end(),boost::mem_fn(&X::f));
}
int main()
{
X x1,x2,x3,x4;
std::vector<X> v;//函数指针类型
v.push_back(x1);
v.push_back(x2);
v.push_back(x3);
v.push_back(x4);
g(v);cout<<"--------------\n";
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
Hello Boost!
Hello Boost!
Hello Boost!
Hello Boost!
--------------
chunli@Linux:~/boost$
boost.function
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include <boost/function.hpp>
struct int_div//这是函数对象
{
float operator()(int x,int y) const
{
std::cout << "in struct ";
return ((float)x)/y;
}
};
float float_div(float x,float y)//这是函数
{
std::cout << "float_div ";
return x/y;
}
void test(boost::function<float(float x,float y)> const& f)
{
std::cout << f(12,35) <<std::endl;
}
int main()
{
boost::function<float(int x,int y)> f1;//既可以接收函数对象,又可以接收函数
f1 =int_div();
std::cout << f1(23,7) << std::endl;
boost::function2<float,int,int> f2;//functionN 只能接收N个参数,第一个参数类型为返回值
f2 =int_div();
std::cout << f2(22,7) << std::endl;
test(&float_div);//函数地址
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
in struct 3.28571
in struct 3.14286
float_div 0.342857
chunli@Linux:~/boost$
包装类的成员函数
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <boost/function.hpp>
struct X
{
int foo(int i)
{
std::cout << "i="<<i<<std::endl;
return 1;
}
};
int main()
{
//使用boost::function
boost::function<int(X*,int)> f;
f =&X::foo;
X x;
f(&x,5);
//使用boost::function N
boost::function2<int,X*,int> f2;//对象指针占一个
f2 = &X::foo;
X x2;
f(&x2,5);
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
i=5
i=5
chunli@Linux:~/boost$
function与functionN[图]
使用function对象的引用的示例[图]
boost.lambda介绍
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
template <int T>
void add(int& src)
{
src+=T;
}
void add5(int& src)
{
src+=5;
}
struct PrintV
{
void operator()(int v)
{
std::cout<< v << " ";
}
};
int main()
{
int a[] = {12,3,5,99,434};
std::for_each(a,a+5,add<12>);//使用函数指针
std::for_each(a,a+5,PrintV());//使用函数对象
std::for_each(a,a+5,add5);
std::for_each(a,a+5,PrintV());
std::cout << std::endl;
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
24 15 17 111 446 29 20 22 116 451
chunli@Linux:~/boost$
lambda出场
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <boost/lambda/lambda.hpp>
int main()
{
using namespace boost::lambda;
int a[] = {1,2,3,4,5};
std::for_each(a,a+5,_1 +=10);//_1 编译器产生函数对象,+=是操作符重载
std::for_each(a,a+5,std::cout<<_1<<" \n");
//lambda还支持做手脚
std::cout << "------\n";
std::for_each(a,a+5,(++ _1,std::cout<<_1<<" \n"));
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
11
12
13
14
15
------
12
13
14
15
16
chunli@Linux:~/boost$
lambda相关的文件[图]
lambda的占位符[图]
占位符总是传元素的引用.
lambda操作符表达式01.png
lambda操作符表达式02.png
lambda操作符表达式03.png
lambda操作符表达式04.png
lambda操作符表达式05.png
延迟常量.png
延迟常量实例,
chunli@Linux:~/boost$ cat main.cpp
#include <iostream>
#include <algorithm>
#include <boost/lambda/lambda.hpp>
int main()
{
using namespace boost::lambda;
int a[] = {11,12,13,14,15,16};
//占位符在左边,正常求值
for_each(a,a+sizeof(a)/sizeof(a[0]),std::cout<<_1<<' ');
std::cout<<std::endl;
//++var(_1)将占位符包裹起来
for_each(a,a+sizeof(a)/sizeof(a[0]),std::cout<< ++var(_1)<<' ');
std::cout<<std::endl;
//立即求值,只进行一次求值,常量不再涉及第二次求值
for_each(a,a+sizeof(a)/sizeof(a[0]),std::cout<<' '<<_1);
std::cout<<std::endl;
//解决办法,只要在表达式的最前端有一个lambda表达式,其他的都当成lambda表达式
int index = 0;
for_each(a,a+sizeof(a)/sizeof(a[0]),std::cout<< --var(index) <<' '<<_1<<' ');//只进行一次求值
std::cout<<std::endl;
return 0;
}
chunli@Linux:~/boost$ g++ main.cpp -Wall && ./a.out
11 12 13 14 15 16
12 13 14 15 16 17
121314151617
-1 12 -2 13 -3 14 -4 15 -5 16 -6 17
chunli@Linux:~/boost$
转载于:https://blog.51cto.com/990487026/1882564