引言
什么是调用操作符和函数对象呢?就是调用操作符看起来像是调用函数,如下设计的一个类,是用来求一个整数的绝对值的,如下类
struct absInt
{
int operator()(int a) {
return (a < 0)? -a: a;
}
};
如下调用
int nVal = -1234;
absInt abs;
int nPosVal = abs.operator()(nVal);
int nabsVal = abs(nVal);
这里使用的是abs(nval),看起来是不是函数的调用,而且还有形参呢,这里使用了重载操作符(),这里只有一个形参,所以默认使用abs()就是调用操作符(),而形参就是nVal,所以就看起来像函数调用。
解说
函数对象或 functor,是可以实现operator ()的任何类类型。 此运算符称作”运算符或应用程序运算符“。 标准模板库主要在容器和算法中使用函数对象作为排序条件。函数对象提供两大优势条函数调用:
(1)函数对象可以包含状态
(2)函数对象属于类型并可用作模板参数
创建函数对象
若要创建功能对象,请创建一个类类型以及operator ()函数,例如:
class Functor
{
public:
int operator()(int a, int b)
{
return a < b;
}
};
int main()
{
Functor f;
int a = 5;
int b = 7;
int ans = f(a, b);
}
main 功能的最后一行显示如何调用函数对象,这看起来像是显示函数调用,但是,它实际调用Functor 中的 operator() 运算符函数。在调用函数对象和函数之间的相似之处就是对象的显示方式。
函数对象和容器
标准模板库。 <functional> 头文件包含一些函数对象。这些功能对象的一个用途是作为容器的排序依据的条件。 例如, set 容器声明如下所示:
template <class Key,class Traits=less<Key>,class Allocator=allocator<Key> >
class set
第二个模板参数是函数对象less。
此函数对象返回true ,如果第一个参数传递给它比传递的第二个参数小于。
因为一些容器进行排序的元素容器,需要比较两个元素方式,这样,使用函数对象完成的。
可以通过创建函数对象拥有排序容器的条件,并指定它在模板用于容器的列表。
函数对象和算法
为函数对象的另一使用在算法。 例如, remove_if 算法声明如下所示:
template<class ForwardIterator, class Predicate>
ForwardIterator remove_if(ForwardIterator _First, ForwardIterator _Last, Predicate _Pred);
remove_if 的最后一个参数是返回布尔值的函数对象。 如果函数对象的结果是 true,则元素通过迭代器_First 和_Last指向的范围中移除 。你可以使用在<functional> 头文件中声明的任何函数对象作为参数_Pred ,当然你也可以创建自己的函数对象。