函数对象

来源:互联网 发布:出版社待遇知乎 编辑:程序博客网 时间:2024/06/09 21:38

函数对象是以函数方式与()结合使用的对象,包括函数名,指向函数的指针和重载了()运算符的类对象。

函数符的概念
生成器是不用参数就可以调用的函数符
一元函数是用一个参数可以调用的函数符
二元函数是用两个参数可以调用的函数符
返回bool值的一元函数是谓词
返回bool值的二元函数是二元谓词

list模板有一个将谓词作为参数的remove_if()成员,该函数将谓词应用于区间中的每个元素,如果谓词返回true,则删除这些元素

bool tooBig(int n){return n>100}list<int>scores;...scores.remove_if(tooBig);

然而如果设计一个tooBig类,则可以使用类成员而不是函数参数来传递额外的信息。

template<class T>class TooBig{private:T cutoff;public:TooBig(const T&t):cutoff(t){}bool operator()(const T &v){return v>cutoff;)

这样就可以将不同的tooBig对象初始化为不同的取舍值,供remove_if()使用

假设有一个接受两个参数的模板函数

template<class T>bool tooBig<const T& val,const T& lim){return val>lim;}

则可以使用类将它转换为单个参数的函数对象

template<class T>class TooBit2{private:T cutoff;public:TooBig2(const T &t):cutoff(t){}bool operator()(const T &v){return tooBig<T>(v,cutoff);}

预定义的函数符
STL定义了多个基本函数符,它们执行诸如将两个值相加,比较两个值是否相等操作。提供这些函数对象是为了支持将函数作为参数的STL函数。
例如:函数transform()它有两个版本,第一个版本接受4个参数,前两个参数是指定容器区间的迭代器,第三个参数是指定将结果复制到哪里的迭代器,最后一个参数是一个函数符,它被应用于区间中的每个元素。
第二个版本使用一个接受两个参数的函数,并将该函数用于两个区间中元素。它用另一个参数标识第二个区间的起始位置。
transfrom(gr8.begin(),gr8.end(),m8.begin(),out,mean)
函数对象mean有两个参数,返回gr8和m8元素的平均值。

头文件functional中定义了多个模板类函数对象
例如:plus<>()函数对象,plus<>类来完成相加运算

transform(gr8.begin(),gr8.end(),m8.begin(),out,plus<double>());

对于所有内置的算术运算符,关系运算符和逻辑运算符,STL都提供了等价的函数符
算术函数符
plus
minus
multiplies
divides
modulus//取余
negate//负
关系函数符
equal_to
not_equal_to
greater
less
greater_equal
less_equal
逻辑函数符
logical_and
logical_or
logical_not

自适应函数符和函数适配器
假设有这种情况,对于容器中的元素,我们希望函数符作用与每个元素,但是函数符是一个二元函数,如果我们向把它转换为一元函数,需要一个函数适配器。
STL提供了函数bind1st和bind2nd
例如我们要将二元函数multiplies()转换为将参数乘以2.5的一元函数,可以这样做
bind1st(multiplies(),2.5)
因此

transform(gr8.begin(),gr8.end(),out,bind1st(multipies<doubel>,2.5));

可以将gr8中每个元素乘以2.5
c++11提供了函数指针和函数符的替代品lambda表达式

原创粉丝点击