6 C++ Boost 函数对象

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程序

[email protected]:~/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;
}
[email protected]:~/boost $ g++  -Wall main.cpp &&./a.out 
11 12 13 14 15 16 
[email protected]:~/boost $

bind与bind2nd,效果一样

[email protected]:~/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;
}
[email protected]:~/boost $ g++  -Wall main.cpp &&./a.out 
11 12 13 14 15 16 
111 112 113 114 115 116 
[email protected]:~/boost $

bind1st 减法

[email protected]:~/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;
}
[email protected]:~/boost $ g++  -Wall main.cpp &&./a.out 
49 48 47 46 45 44 
[email protected]:~/boost $

bind1st 与bind 做减法

[email protected]:~/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;
}
[email protected]:~/boost $ g++  -Wall main.cpp &&./a.out 
99 98 97 96 95 94 
[email protected]:~/boost $

bind2nd调用仿函数

[email protected]:~/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;
}
[email protected]:~/boost $ g++  -Wall main.cpp &&./a.out 
51 52 53 54 55 56 
[email protected]:~/boost $

bind 不需要ptr_fun适配

[email protected]:~/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;
}
[email protected]:~/boost $ g++  -Wall main.cpp &&./a.out 
51 52 53 54 55 56 
[email protected]:~/boost $

std:bind2nd 与 boost:bind

[email protected]:~/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;
}
[email protected]:~/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
[email protected]:~/boost $



当参数大于2个,std::bind已经没办法了,boost::bind限10个

[email protected]:~/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;
}
[email protected]:~/boost $ g++  -Wall main.cpp &&./a.out 
31 32 33 34 35 36 
[email protected]:~/boost $


bind_api[图]

bind api (0个参数,1个参数)

解读:

bind实际就是一个函数

无参数的bind,需要一个函数对象

bind用于函数 以及 函数指针

[email protected]:~/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;
}
[email protected]:~/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
[email protected]:~/boost$

bind用于函数对象

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
[email protected]:~/boost$


bind用于函数对象,(用引用避免函数对象的拷贝)

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
6
[email protected]:~/boost$



bind 函数成员指针

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
a=5
a=5
a=5
a=5
[email protected]:~/boost$



bind 嵌套

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
f1() i=5
f1() i=5
f2() i=5
f2() i=5
[email protected]:~/boost$


关于mem_fun[图]

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
Hello Boost!
Hello Boost!
Hello Boost!
Hello Boost!
--------------
[email protected]:~/boost$

boost.function

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
in struct 3.28571
in struct 3.14286
float_div 0.342857
[email protected]:~/boost$



包装类的成员函数

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
i=5
i=5
[email protected]:~/boost$


function与functionN[图]


使用function对象的引用的示例[图]



boost.lambda介绍

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
24 15 17 111 446 29 20 22 116 451 
[email protected]:~/boost$



lambda出场

[email protected]:~/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;
}
[email protected]:~/boost$ g++ main.cpp -Wall && ./a.out 
11 
12 
13 
14 
15 
------
12 
13 
14 
15 
16 
[email protected]:~/boost$


lambda相关的文件[图]

lambda的占位符[图]

占位符总是传元素的引用.


lambda操作符表达式01.png

lambda操作符表达式02.png

lambda操作符表达式03.png

lambda操作符表达式04.png

lambda操作符表达式05.png


延迟常量.png

延迟常量实例,

[email protected]:~/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;
}
[email protected]:~/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 
[email protected]:~/boost$
时间: 2024-10-23 11:32:18

6 C++ Boost 函数对象的相关文章

boost库在工作(15)绑定器与函数对象之三

前面已经可以优美地解决两个参数的函数给算法for_each调用了,但是又会遇到这样的一种情况,当需要三个参数或者三个以上的参数给算法for_each调用呢?从STL里的绑定器bind1st,显然是不行了,因为它最多只支持两个参数,那还有什么办法呢?这时就需要使用boost库里强大的绑定器bind了.它不仅适用的情况比STL库里的多,还更加方便,更加人性化.下面就来看看怎么样绑定三个参数的类成员函数的例子,如下: [cpp] view plaincopy //调用类的成员函数,但参数两个以上. /

C++中的函数对象(一)

STL中的函数对象,大多数STL类属算法(以及某些容器类)可以以一个函数对象作为参数.引入函数对象的目的是为了使算法的功能富于变化,从而增强算法的通用性. 所谓函数对象,是指一段代码实体,它可以不带参数,也可以带有若干参数,其功能是获得一个值,或者改变操作的状态.在C++编程中,任何普通的函数都满足这个定义,而且,任何一个重载了运算符operator()的类的对象也都满足这一定义,称为函数对象. 普通函数 int multfun(int x, int y) { return x*y; } 或者下

python--函数的返回值、函数参数的使用、名称空间与作用域、函数嵌套、函数对象

今天学习内容有函数的返回值.函数参数的使用.名称空间与作用域.函数嵌套. 下来我们一一查看. 函数的返回值 看几个栗子: def func(x): return x**2 y=func(10) print(y) def foo(): return None res=foo() print(res) def foo(): return{'a':1} res=foo() print(res['a']) def foo(): return {'a':1},1,'a',[1,2] res=foo() p

Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数

一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(First-Class Object)呢? 在 Python 中万物皆为对象,函数也不例外,函数作为对象可以赋值给一个变量.可以作为元素添加到集合对象中.可作为参数值传递给其它函数,还可以当做函数的返回值,这些特性就是第一类对象所特有的. 1.函数身为一个对象,拥有对象模型的三个通用属性:id.类型.和值.

STL算法设计理念 - 函数对象和函数对象当參数和返回值

函数对象: 重载函数调用操作符的类.其对象常称为函数对象(function object),即它们是行为类似函数的对象. 一个类对象,表现出一个函数的特征,就是通过"对象名+(參数列表)"的方式使用一个类对象,假设没有上下文,全然能够把它看作一个函数对待. 这是通过重载类的operator()来实现的. "在标准库中.函数对象被广泛地使用以获得弹性".标准库中的非常多算法都能够使用函数对象或者函数来作为自定的回调行为: demo #include <iostr

谓词函数、函数对象

从概念上讲,函数对象用作函数的对象:但是从实现上来说,函数对象时实现了 operate()的类的对象. 虽然函数和函数指针也可以归为函数对象,但实现了operate()的类的对象才能保存状态,才能用于STL. 我们直接看定义: 一元函数:接受一个参数的函数,如f(x). 一元谓词函数:如果一元函数返回一个BOOL类型的值,则该函数称为谓词. 二元函数:接受2个参数的函数,如f(x,y). 二元谓词函数:如果二元函数返回一个BOOL值,则该函数称为二元谓词. 之所以给返回布尔类型的函数对象专门命名

函数对象(仿函数 functor)

简单地说,函数对象就是一个重载了()运算符的类实例,它可以像一个函数一样使用. #include <iostream> using namespace std; class Add { public: int operator ()(const int &a, const int &b) { return (a + b); } double operator ()(const double &a, const double &b) { return (a + b

【Python】函数对象

转:作者:Vamei 出处:http://www.cnblogs.com/vamei 函数也是一个对象,具有属性(可以使用dir()查询).作为对象,它还可以赋值给其它对象名,或者作为参数传递. lambda函数 在展开之前,我们先提一下lambda函数.可以利用lambda函数的语法,定义函数.lambda例子如下: func = lambda x,y: x + y print func(3,4) lambda生成一个函数对象.该函数参数为x,y,返回值为x+y.函数对象赋给func.func

11、函数对象、函数的嵌套、名称空间与作用域

一.函数对象 函数对象,函数是第一类对象,即函数可以当做数据传递 具体特点: 1.可以被引用: 1 def foo(): 2 print('from foo') 3 4 func=foo 5 6 print(foo) 7 print(func) 8 func() 2.可以当作参数传递 1 def foo(): 2 print('from foo') 3 4 def bar(func): 5 print(func) 6 func() 7 8 bar(foo) 3.返回值可以是函数 1 def fo