一、概述
仿函数是早期命名,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>。
逻辑运算 | 格式 |
---|---|
逻辑与 And | logical_and<T> |
逻辑或 Or | logical_or<T> |
逻辑非 Not | logical_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>())