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$
本文出自 “魂斗罗” 博客,谢绝转载!
原文地址:http://990487026.blog.51cto.com/10133282/1882564