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