浅析stl仿函数

1. 仿函数的概念

仿函数(functors)是早期的命名,c++标准规格定案后所采用的新名称是函数对象(function objects)。仿函数是一个能行使函数功能的,必须重载operator()运算符,调用仿函数,就是通过类对象调用重载后的operator运算符。

2. 仿函数的主要作用

以stl中的仿函数为例,stl中的提供的算法,往往有两个版本,一个是最直观的某种运算,另一种是泛化的演算流程,允许用户"以template参数来指定所要采行的策略",仿函数通常用于指定某种操作来当作算法的参数,流程是通过仿函数产生一个对象,通过此对象作为该算法的参数。

通过上述描述,可以看出仿函数其实是给算法提供一种策略,使得stl算法更加灵活,而灵活的关键,在于stl仿函数的可配接行

例如标准库中的find函数:

template <class InputIterator, Class T>
InputIterator find(InputIterator first,
	InputIterator last,
	const T& value)
{
	while (first != last && *first != value)
		++first;
	return first;
}

//Predicate为仿函数
template <class InputIterator, class Predicate>
InputIterator find(InputIterator first,
	InputIterator last,
	Predicate pred)
{
	while (first != last && !pred(*first))
		++first;
	return first;
}

3. stl仿函数的分类

以操作数(operand)的个数划分,分为一元和二元仿函数;

以功能划分,可分为算数运算(Arithmetic)、关系运算(Rational)和逻辑运算(Logical);

4. 按操作数划分

4.1 unary_function

unary_function用来呈现一元函数的参数型别和返回值型别。定义如下:

template <class Arg, class Result>
struct unary_function
{
	typedef Arg argument_type;
	typedef Result result_type;
};

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

//配接器表示某个仿函数的逻辑负值
template <class Predicate>
struct unary_negate
{
	...
public:
	bool operator() (const typename Predicate::argument_type& x) {
		...
	}
};

4.2 binary_function

binary_function用来呈现二元函数的第一参数的型别,第二参数的型别以及回返值型别。其定义如下:

template <class Arg1, class Arg2, class Result>
struct binary_function
{
	typedef Arg1 first_argument_type;
	typedef Arg2 second_argument_type;
	typedef Result result_type;
};

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

//配接器(adapter)将二元仿函数转化为一元仿函数
template <class Operation>
struct binary1st
{
	...
protected:
	Operation op;
	typename Operation::first_argument_type value;

public:
	typename Operation::result_type
		operator() (const typename Operation::second_argument_type& x) const {
		...
	}
};

仿函数继承unary_function或者binary_function的意义: 可适配adaptable, 便于Function Adapt(适配器)“提问问题”(通过typedef的参数回答),后续将继续展开。

5. 按功能划分

5.1 算数类仿函数

加法: plus<T>

减法: minus<T>

乘法: multiplies<T>

除法: divides<T>

模取(modules): modules<T>

否定(negation): negate<T>

eg:

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

5.2 关系运算类仿函数

等于(equality): equal_to<T>

不等于: not_equal_to<T>

大于: greater<T>

大于或等于: greater_equal<T>

小于: less<T>

小于或等于: less_equal<T>

eg:

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

5.3 逻辑运算仿函数

逻辑运算And: logical_and<T>

逻辑运算Or: logical_or<T>

逻辑运算Not: Loical_not<T>

eg:

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

6. stl仿函数使用实例

使用stl中的sort对一个int型数组进行排序。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool myFunc(int i, int j)
{
	return (i < j);
}

struct myclass
{
	bool operator() (int i, int j)
	{
		return (i < j);
	}
}myObj;

int main()
{
	int a[] = { 21,23,11,13,56,12,47,29 };
	vector<int> myvec(a, a + 8);

	sort(myvec.begin(), myvec.begin() + 4);
	sort(myvec.begin() + 4, myvec.end(), myFunc);
	sort(myvec.begin(), myvec.end(), myObj);
	sort(myvec.rbegin(), myvec.rend());

	system("pause");
    return 0;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值