仿函式是什麼?仿函式什麼時候必須繼承一元或者二元謂詞

y_dd發表於2020-10-26

什麼是仿函式?為什麼有些仿函式必須要繼承unary_function或者binary_function

仿函式的概念

使用起來像函式一樣的東西,實際是一個物件
主要功能是為了搭配STL的演算法

template<typename T>
struct myPlus
{
	T operator()(const T& a1, const T& a2) const { return a1 + a2; }

};
void test05()
{
	myPlus<int> pob;
	cout << pob(5, 9) << endl;
	cout << myPlus<int>()(7, 8) <<endl;
}

STL中的plus仿函式的實現(vs中參看的原始碼)

template<class _Ty = void>
	struct plus
	{	// functor for operator+
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty first_argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty second_argument_type;
	_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty result_type;

	constexpr _Ty operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator+ to operands
		return (_Left + _Right);
		}
	};

可配接的仿函式

STL定義了兩個Class,unary_function和binary_function ,繼承其中一個,就擁有了其中的型別,這時候就是可以配接了。以下摘是VS的原始碼

template<class _Arg,
	class _Result>
	struct unary_function
	{	// base class for unary functions
	typedef _Arg argument_type;
	typedef _Result result_type;
	};

template<class _Arg1,
	class _Arg2,
	class _Result>
	struct binary_function
	{	// base class for binary functions
	typedef _Arg1 first_argument_type;
	typedef _Arg2 second_argument_type;
	typedef _Result result_type;
	};

仔細觀察就發現這兩個類其實沒有任何member,只有一些型別,那麼作用呢?

什麼時候必須定義可配接的仿函式

初學時候有疑惑為什麼有些不繼承上面兩個類的仿函式仍然能夠用於演算法,那到底什麼時候必須定義呢?

template<typename T>
struct MyGreater:public binary_function<T, T, T>
{
	T operator()(const T& a1, const T& a2)const { return a1 > a2; }
};
void test06()
{
	vector<int> v = { 23, 96, 4, 5 };
	vector<int>::iterator pos = find_if(v.begin(), v.end(), bind2nd(MyGreater<int>(), 23));
	if (pos != v.end())
	{
		cout << *pos << endl;
	}
}

如上程式碼就必須繼承binary_function!
原因在於如下bind2nd的原始碼如下:

template<class _Fn,
	class _Ty>
	_NODISCARD inline binder2nd<_Fn> bind2nd(const _Fn& _Func, const _Ty& _Right)
	{	// return a binder2nd functor adapter
	typename _Fn::second_argument_type _Val(_Right);
	return (binder2nd<_Fn>(_Func, _Val));
	}

注意到了沒有,用到了型別 _Fn::second_argument_type,如果不繼承binary_function你就沒法獲取到這個型別,特別當某些仿函式你使用的是庫函式,而不是自己定義的函式。
綜上,STL仿函式應該具備函式介面卡(配接器)使用的能力,才能更好的用於演算法

相關文章