STL之仿函数

一、概述

仿函数是早期命名,C++标准后采用新名称函数对象。函数对象即指具有函数特质的对象,即一个行为类似函数的对象。通过在仿函数对象后面加上( )实现函数调用,示例程序如下:

#include<functional>
#include<iostream>
using namespace std;

int main()
{
    greater<int> ig;
    cout << boolalpha << ig(4, 6) << endl; //false
    cout << greater<int>()(6, 4) << endl;  //true
    return 0;
}

greater<int>( )(6, 4)的用法是greater<int>( )产生一个临时的(无名)对象,之后的(4,6)才是指定两个参数4,6。当包含无名对象的语句执行结束时,无名对象的生命周期也就结束了。仿函数在STL中的位置如图所示,是作为STL某些算法的参数出现的。
这里写图片描述
STL仿函数若按照操作数个数分类可分为一元和二元仿函数,若以功能划分,可分为算术运算、关系运算、逻辑运算三大类。程序中若要使用仿函数,应该含入<functional>头文件。
比起一般函数,仿函数具有以下优点:
1. 仿函数是智能型函数(行为类似函数的对象)。
    仿函数是行为类似函数的对象,同时可以拥有成员函数和成员变量,这意味着仿函数可以拥有状态。
2. 每个仿函数都有自己的型别。
3. 仿函数比一般函数快。

二、预定义仿函数分类

  • 算术类仿函数
    STL内建的算术类仿函数,支持加法、减法、乘法、除法、模数和否定运算,除了否定运算为一元运算,其他都是二元运算且支持模版参数template<class T>。
运算格式
加法plus<T>
减法minus<T>
乘法multiplies<T>
除法divides<T>
模取modulus<T>
否定negate<T>


以下为6个算术类仿函数

template<class T>
struct plus : public binary_function<T, T, T> {
    T operator()(const T& x, const T& y) const { return x + y; }
};

template<class T>
struct minus : public binary_function<T, T, T> {
    T operator()(const T& x, const T& y) const { return x - y; }
};

template<class T>
struct multiplies : public binary_function<T, T, T> {
    T operator()(const T& x, const T& y) const { return x * y; }
};

template<class T>
struct divides : public binary_function<T, T, T> {
    T operator()(const T& x, const T& y) const { return x / y; }
};

template<class T>
struct plus : public binary_function<T, T, T> {
    T operator()(const T& x, const T& y) const { return x + y; }
};

template<class T>
struct modulus : public binary_function<T, T, T> {
    T operator()(const T& x, const T& y) const { return x % y; }
};

template<class T>
struct negate : public unary_function<T, T> {
    T operator()(const T& x) const { return -x; }
};

这些仿函数所产生的对象,用法和一般函数完全相同。当然也可以产生一个无名的临时对象来履行函数功能。下面的示例显示两种仿函数用法:

#include<functional>
#include<iostream>
using namespace std;

int main()
{
    //第一种用法
    plus<int> plusobj;
    minus<int> minusobj;
    multiplies<int> multipliesobj;
    divides<int> dividesobj;
    modulus<int> modulusobj;
    negate<int> negateobj;

    cout << plusobj(3, 5) << endl;
    cout << minusobj(3, 5) << endl;
    cout << multipliesobj(3, 5) << endl;
    cout << dividesobj(3, 5) << endl;
    cout << modulusobj(3, 5) << endl;
    cout << negateobj(3) << endl;

    //第二种用法
    cout << plus<int>()(3, 5) << endl;
    cout << minus<int>()(3, 5) << endl;
    cout << multiplies<int>()(3, 5) << endl;
    cout << divides<int>()(3, 5) << endl;
    cout << modulus<int>()(3, 5) << endl;
    cout << negate<int>()(3) << endl;

    return 0;
}

运行结果:
这里写图片描述

  • 关系运算类仿函数
    STL内建的关系运算类仿函数,支持等于、不等于、大于、大于等于、小于、小于等于等6种运算,每个都是二元运算且支持模版参数template<class T>。
关系运算格式
等于equal_to<T>
不等于not_equal_to<T>
大于greater<T>
大于等于greater_equal<T>
小于less<T>
小于等于less_equal<T>


以下为6个关系运算类仿函数

template<class T>
struct equal_to : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x == y; }
};

template<class T>
struct not_equal_to : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x != y; }
};

template<class T>
struct greater : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x > y; }
};

template<class T>
struct greater_equal : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x >= y; }
};

template<class T>
struct less : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x < y; }
};

template<class T>
struct less_equal : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x <= y; }
};

这些仿函数所产生的对象,用法和一般函数完全相同。当然也可以产生一个无名的临时对象来履行函数功能。下面的示例显示两种仿函数用法:

#include<functional>
#include<iostream>
using namespace std;

int main()
{
    //第一种用法
    equal_to<int> equal_to_obj;
    not_equal_to<int> not_equal_to_obj;
    greater<int> greater_obj;
    greater_equal<int> greater_equal_obj;
    less<int> less_obj;
    less_equal<int> less_equal_obj;

    cout << equal_to_obj(3, 5) << endl;
    cout << not_equal_to_obj(3, 5) << endl;
    cout << greater_obj(3, 5) << endl;
    cout << greater_equal_obj(3, 5) << endl;
    cout << less_obj(3, 5) << endl;
    cout << less_equal_obj(3, 5) << endl;

    //第二种用法
    cout << equal_to<int>()(3, 5) << endl;
    cout << not_equal_to<int>()(3, 5) << endl;
    cout << greater<int>()(3, 5) << endl;
    cout << greater_equal<int>()(3, 5) << endl;
    cout << less<int>()(3, 5) << endl;
    cout << less_equal<int>()(3, 5) << endl;

    return 0;
}

运行结果:
这里写图片描述

  • 逻辑运算类仿函数
    STL内建的逻辑运算仿函数,支持逻辑运算中And、Or、Not三种运算,前两个是二元运算,Not是一元运算且支持模版参数template<class T>。
逻辑运算格式
逻辑与 Andlogical_and<T>
逻辑或 Orlogical_or<T>
逻辑非 Notlogical_not<T>


以下为3个逻辑运算类仿函数

template<class T>
struct logical_and : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x && y; }
};

template<class T>
struct logical_or : public binary_function<T, T, bool> {
    bool operator()(const T& x, const T& y) const { return x || y; }
};

template<class T>
struct logical_not : public unary_function<T, bool> {
    bool operator()(const T& x) const { return !x; }
};

这些仿函数所产生的对象,用法和一般函数完全相同。当然也可以产生一个无名的临时对象来履行函数功能。下面的示例显示两种仿函数用法:

#include<functional>
#include<iostream>
using namespace std;

int main()
{
    //第一种用法
    logical_and<int> and_obj;
    logical_or<int> or_obj;
    logical_not<int> not_obj;

    cout << and_obj(3, 5) << endl;
    cout << and_obj(0, false) << endl;
    cout << or_obj(3, 5) << endl;
    cout << or_obj(3, 0) << endl;
    cout << not_obj(true) << endl;

    //第二种用法
    cout << logical_and<int>()(3, 5) << endl;
    cout << logical_or<int>()(3, 5) << endl;
    cout << logical_not<int>()(3) << endl;

    return 0;
}

运行结果:
这里写图片描述

三、自制仿函数

自制仿函数即指通过自己定义一个仿函数类,然后生成仿函数对象进行函数调用。而在仿函数类中,要重载operator( )运算符以成为仿函数类。例如:

class AddValue {
    private:
        int theValue;
    public:
        AddValue(int v) : theValue(v) { }
        void operator() (int& elem) const {
            elem += theValue;
        }
};

上例中的AddValue仿函数类生成函数对象时需要首先构函数对象,传入theValue的初值,如AddValue(10)。
也可以使用结构体进行构造,如下。在使用时只需传入型别参数。

template<class T>
struct display{
    void operator()(const T& x) {
        std::cout << x << ' ';
    }
};
....
vector<int> coll;
for_each(coll.begin(), coll.end(), display<int>())
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值