函数对象

Bjarne Stroustrup的解答已经非常经典了——在某种方式上表现得象一个函数的对象。典型地,它是指一个类的实例,这个类定义了应用操作符operator()。 
一个类对象,表现出一个函数的特征,就是通过“对象名(参数列表)”的方式使用一个类对象,如果没有上下文,完全可以把它看作一个函数对待。这是通过重载类的operator()(...)来实现的。比如,对于调用int s = sum(1, 2);,你可能把它看作一个函数调用: 
int sum(int i, int j) { return (i + j); }
int s = sum(1, 2);
但很可能它是一个函数对象:
class Sum

public:
    int operator()(int i, int j) { return (i + j); } 
};

Sum sum;
int s = sum(1, 2); 

而大多数情况是:
template <class T> 
class Sum

public: 
    T operator()(T i, T j) { return (i + j); } 
}; 

Sum<int> sum; 
int s = sum(1, 2); 

“在标准库中,函数对象被广泛地使用以获得弹性”,标准库中的很多算法都可以使用函数对象或者函数作为自定的回调行为。


示例:

#include <iostream>
#include <queue>
#include <ctime>
using namespace std;


// 函数对象类
template<typename T>
class MyComparator
{
public:
    bool operator()(T a, T b)
    {
        // 谁离60越近,谁的优先级就越高
        return abs(a - 60) > abs(b - 60);
    }
};


int main()
{
    // 指定 priority_queue 的比较函数对象类为 MyComparator
    priority_queue<int, deque<int>, MyComparator<int> > pq;
    srand((unsigned int) time(0));
    int i;


    for (i = 0; i < 10; i++)
    {
        // 产生10个0-99间的随机数 ,并压入队列
        int rd = rand() % 100;
        pq.push(rd);
        cout << rd << " ";
    }


    cout << endl;


    // 按函数对象输出并弹出元素
    for (i = 0; i < 10; i++)
    {
        cout << pq.top() << " ";
        pq.pop();
    }


    cout << endl;


    system("pause");
    return 0;
}

在默认情况下,priority_queue的第3个参数为less,这是STL中预定义的函数对象,预定义的函数对象如下所示:

plus

 

 

 

算术

返回两个数的和:a+b    

minus

返回两个数的差:a-b

multiplies

返回两个数的乘积:a*b

divides

返回两个数的商:a/b

mudulus

返回两个数的模:a%b

negate

返回某个数的相反数:-a

equal_to

 

 

关系   

判断两个数是否相等:a==b

not_equal_to

判断两个数是否不等:a!=b

greater

判断第一个数是否大于第二个数:a>b

less

判断第一个数是否小于第二个数:a<b

greate_equal

判断第一个数是否大于等于第二个数:a>=b

less_equal

判断第一个数是否小于等于第二个数:a<=b

logical_and

 

逻辑

返回两个数的逻辑与结果:a&&b

logical_or

返回两个数的逻辑或结果:a||b

logical_not

返回某个数的逻辑非结果:!a

使用方法:
    plus<int> x;
    cout << x(10,20) << endl;

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

另一个例子:

/*
 * 函数对象其实就是一种类似于函数的类对象,函数对象类必须重载operator()函数,往往以内联方式
 */


// 函数对象类(这里给出的是模板,当然也可以是普通类)
template<typename T> class MyComparator
{
public:
    bool operator ()(const T& a, const T& b)
    {
        return (a < b);
    }
};


int main()
{
    MyComparator<int> x;


    if (x(1, 0))
    {
        printf("%s\n", "true");
    }
    else
    {
        printf("%s\n", "false");
    }


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值