淺析stl仿函式

Stay alone發表於2020-11-20

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;
}

 

 

 

 

相關文章