您的位置:首页 > 其它

STL之仿函数

2017-04-11 17:04 197 查看

一、概述

仿函数是早期命名,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>())
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl 仿函数