Boost.Function指南
2009-01-01 22:21
176 查看
原文:http://www.boost.org/doc/libs/1_37_0/doc/html/function/tutorial.html
原作者:boost
版权:本文为Boost的译文,遵守BoostSoftwareLicense-Version1.0协议
Boost.Function指南
基本用法
自由函数
成员函数
函数对象引用
比较Boost.Function和函数对象
Boost.Function有两种语法形式,首选形式和可移槙形式。首选形式更符合C++语言习惯,使用更少量的模板形参,具有更强的可读性。遗憾的是,由于编译器自身的bug,使得并非所有的编译器都支持首选形式。Boost.Function支持的可移槙形式可以在所有编译器上运行。可查阅下表来为你的编译器选择一种适合的形式。
[thead]
如果上表没有你所使用的编译器,请尝试使用首选语法形式,并把使用结果报告给Boost邮件列表,使上表保持最新的信息。
[thead]
默认情况,函数对象包装器是空的,我们可以创建一个函数对象并赋给f。
现在我们可以使用f去执行底层的函数对象int_div。
任何与f兼容的函数对象都可以分配给f。若int_div声明接受两个long类型的操作数,由f传递给int_div的参数会产生隐式转换,而无须用户介入。这一规则适用于任何可拷贝构造的参数类型,甚至是引用和数组。
[thead]
调用一个没有包含函数对象的函数对象包装器,违背了它的前置条件,如同尝试在空函数指针上调用一样,将会抛出bad_function_call异常。可以在boolean语境中使用函数对象包装器(如果包装器不为空,那么它取值为true),或比较函数对象包装器与0来检查它是否为空函数对象包装器,例如:
另外,empty()函数可以告知该包装器是否为空。
最后,可以清除函数目标,通过用0给它赋值,或调用clear()成员函数,例如:
注意符号&不是必须的,除非你正使用MicrosoftVisualC++Version6。
[thead]
存在一些库支持参数绑定,下面是三个支持参数绑定库的汇总:
·
Bind。该库允许为任何函数对象进行参数绑定,同时是轻量级的和具有很好的移槙性。
·
C++标准库,一起使用std::bind1st和std::mem_fun把对象绑定到成员函数指针,以供Boost.Function使用:
[thead]
·
Lambda库,它使用非常地道的C++语法,提供一种强大的组合机制来构造函数对象。Lambda要求编译器要相当好地尊盾C++标准。
[thead]
这里f没有拷贝a_function_object对象,f2也一样,只是关注f中指向a_function_object的引用。另外,使用函数对象的引用给Boost.Function赋值,或传给它的构造函数,将不会抛出异常。
EqualityComparable或已重载
函数对象包装器与
原作者:boost
版权:本文为Boost的译文,遵守
Boost.Function指南
Boost.Function有两种语法形式,首选形式和可移槙形式。首选形式更符合C++语言习惯,使用更少量的模板形参,具有更强的可读性。遗憾的是,由于编译器自身的bug,使得并非所有的编译器都支持首选形式。Boost.Function支持的可移槙形式可以在所有编译器上运行。可查阅下表来为你的编译器选择一种适合的形式。
首选语法 | 可移槙语法 |
GNUC++2.95.x, 3.0.x,3.1.x ComeauC++4.2.45.2 SGIMIPSpro7.3.0 IntelC++5.0,6.0 Compaq'scxx6.2 MicrosoftVisualC++ 7.1 | 支持首选语法的所有编译器 MicrosoftVisualC++ 6.0,7.0 BorlandC++5.5.1 SunWorkShop6 update2C++5.3 Metrowerks CodeWarrior8.1 |
基本用法
简单地说,函数包装器就是function类模板的实例,通过指定返回类型和参数类型,类似于C++函数类型。可以提供任意个数的参数,但不能超过实现时定义的个数限制(默认最大值为10)。下面声明了函数对象包装器f,它要求两个int参数,并返回float结果。首选语法 | 可移槙语法 |
<float(intx,inty)>f;[/code] | <float,int,int>f;[/code] |
structint_div{
floatoperator()(intx,inty)const{return((float)x)/y;};
};
f=int_div();
现在我们可以使用f去执行底层的函数对象int_div。
std::cout<<f(5,3)<<std::endl;
任何与f兼容的函数对象都可以分配给f。若int_div声明接受两个long类型的操作数,由f传递给int_div的参数会产生隐式转换,而无须用户介入。这一规则适用于任何可拷贝构造的参数类型,甚至是引用和数组。
首选语法 |
<void(intvalues[],intn,int&sum,float&avg)>sum_avg;[/code] |
可移槙语法 |
<void,int*,int,int&,float&>sum_avg;[/code] |
voiddo_sum_avg(intvalues[],intn,int&sum,float&avg)
{
sum=0;
for(inti=0;i<n;i++)
sum+=values[i];
avg=(float)sum/n;
}
sum_avg=&do_sum_avg;
调用一个没有包含函数对象的函数对象包装器,违背了它的前置条件,如同尝试在空函数指针上调用一样,将会抛出bad_function_call异常。可以在boolean语境中使用函数对象包装器(如果包装器不为空,那么它取值为true),或比较函数对象包装器与0来检查它是否为空函数对象包装器,例如:
if(f)
std::cout<<f(5,3)<<std::endl;
else
std::cout<<"fhasnotarget,soitisunsafetocall"<<std::endl;
另外,empty()函数可以告知该包装器是否为空。
最后,可以清除函数目标,通过用0给它赋值,或调用clear()成员函数,例如:
f=0;
自由函数
自由函数指针可以看成独立的函数对象,拥用const的函数调用操作符;因此它可以直接用在函数对象包装器中:floatmul_ints(intx,inty){return((float)x)*y;}
f=&mul_ints;
注意符号&不是必须的,除非你正使用MicrosoftVisualC++Version6。
成员函数
很多系统中,回调通常是调用某个特定类的成员函数。这通常涉及“参数绑定”,并超出了Boost.Function的范围。然而Boost.Function支持直接使用成员函数,因此下面代码是合法的:structX{
intfoo(int);
};
首选语法 | 可移槙语法 |
<int(X*,int)>f;[/code] f=&X::foo; Xx; f(&x,5); | <int,X*,int>f;[/code] f=&X::foo; Xx; f(&x,5); |
·
·
C++标准库,一起使用std::bind1st和std::mem_fun把对象绑定到成员函数指针,以供Boost.Function使用:
首选语法 | 可移槙语法 |
[code]<int(int)>f;[/code] Xx; f=std::bind1st( std::mem_fun(&X::foo),&x); f(5);//Callx.foo(5) | [code]<int,int>f;[/code] Xx; f=std::bind1st( std::mem_fun(&X::foo),&x); f(5);//Callx.foo(5) |
Lambda库,它使用非常地道的C++语法,提供一种强大的组合机制来构造函数对象。Lambda要求编译器要相当好地尊盾C++标准。
函数对象引用
在某些情况下,让Boost.Function去拷贝一个函数对象是昂贵的(或语义错误的)。在此情况下,很可能要求Boost.Function只保存函数对象的引用。可通过使用ref和cref函数把引用包装成一个函数对象来实现。首选语法 | 可移槙语法 |
stateful_typea_function_object; <int(int)>f;[/code] f=[code](a_function_object);[/code] <int(int)>f2(f);[/code] | stateful_typea_function_object; <int,int>f;[/code] f=[code](a_function_object);[/code] <int,int>f2(f);[/code] |
比较Boost.Function和函数对象
函数对象包装器可以通过==或!=与能储存在该包装器内的任何函数对象作比较。若函数对象包装器内包含的是函数对象,则把内在的函数对象与给定的函数对象作比较(它们必须是)。例如:boost::function_equal
intcompute_with_X(X*,int);
f=&X::foo;
assert(f==&X::foo);
assert(&compute_with_X!=f);
函数对象包装器与
reference_wrapper
的实例比较时,则把
reference_wrapper
中对象的地址和函数对象包装器内储存对象的地址作比较。
a_stateful_objectso1,so2;
f=[code](so1);[/code]boost::ref
assert(f==[code](so1));[/code]boost::ref
assert(f==so1);//Onlyifa_stateful_objectisEqualityComparable
assert(f!=[code](so2));[/code]boost::ref
相关文章推荐
- C++“准”标准库Boost学习指南(11):Boost.Function
- boost::function详解
- boost::function用法详解
- 以boost::function和boost:bind取代虚函数
- Boost下载安装编译配置使用指南(含Windows和Linux)
- 以boost::function和boost:bind取代虚函数
- [Elasticsearch] 控制相关度 (五) - function_score查询及field_value_factor,boost_mode,max_
- boost源码剖析之:泛型函数指针类boost::function(rev#3)
- Boost 下载安装编译配置使用指南(含Windows和Linux)
- boost源码剖析之:泛型函数指针类boost::function(rev#3)
- boost翻译(4):boost.iostreams指南--使用Devices
- boost bind使用指南
- C++ Boost Thread 编程指南
- 【Boost】boost库中function的用法
- [置顶] 编程模仿boost::function和boost::bind
- C++ Boost Thread 编程指南
- boost::function用法详解
- boost::function 通过boost::bind调用类成员函数
- boost::function 通过boost::bind调用类成员函数
- XGBoost参数调优完全指南(附Python代码)