C++標準庫—仿函數

分類:編程 時間:2017-02-07

概念
仿函數(functor),就是使一個類的使用看上去象一個函數。其實現就是類中實現一個operator(),這個類就有了類似函數的行為,就是一個仿函數類了。
  有些功能的的代碼,會在不同的成員函數中用到,想復用這些代碼。

1)公共的函數,可以,這是一個解決方法,不過函數用到的一些變量,就可能成為公共的全局變量,再說為了復用這麽一片代碼,就要單立出一個函數,也不是很好維護。

2)仿函數,寫一個簡單類,除了那些維護一個類的成員函數外,就只是實現一個operator(),在類實例化時,就將要用的,非參數的元素傳入類中。

使用一般函數:

#include<iostream>
#include<vector>
#include<algorithm>
#include<iterator>

using namespace std;

template<class T>
inline void PRINT_ELEMENTS(const T& coll,const char * optcstr="")
{
	typename T::const_iterator pos;
	cout<<optcstr;
	for(pos=coll.begin();pos!=coll.end();++pos)
	{
		cout<<*pos<<" ";
	}
	cout<<endl;
}

int square(int value)
{
	return value*value;
}

template<int theValue>
void add(int &elem)
{
	elem+=theValue;
}

int main()
{
	vector<int> coll1;
	vector<int> coll2;

	for(int i=1;i<=9;i++)
	{
		coll1.push_back(i);
	}
	PRINT_ELEMENTS(coll1,"initialized: ");

	for_each(coll1.begin(),coll1.end(),add<10>);

	PRINT_ELEMENTS(coll1,"after adding 10: ");

	transform(coll1.begin(),coll1.end(),back_inserter(coll2),square);

	PRINT_ELEMENTS(coll2,"squared: ");

	system("pause");
	return 0;
}

使用仿函數:

//仿函數
#include<iostream>
#include<list>
#include<algorithm>

using namespace std;

template<class T>
inline void PRINT_ELEMENTS(const T& coll,const char * optcstr="")
{
	typename T::const_iterator pos;
	cout<<optcstr;
	for(pos=coll.begin();pos!=coll.end();++pos)
	{
		cout<<*pos<<" ";
	}
	cout<<endl;
}

class AddValue
{
private:
	int theValue;
public:
	AddValue(int v):theValue(v) {}
	void operator()(int &elem) const
	{
		elem+=theValue;
	}
};

int main()
{
	list<int> coll;

	for(int i=1;i<=9;i++)
	{
		coll.push_back(i);
	}

	PRINT_ELEMENTS(coll,"initialized: ");

	for_each(coll.begin(),coll.end(),AddValue(10));

	PRINT_ELEMENTS(coll,"after adding 10: ");

	for_each(coll.begin(),coll.end(),AddValue(*coll.begin()));

	PRINT_ELEMENTS(coll,"after adding first element: ");

	system("pause");
	return 0;
}

凡是行為像函數,那麽這個對象就是函數。仿函數就是這個意思,但是STL中為什麽要用仿函數而不直接用函數呢?

首先STL是一個有自己規則的框架,函數指針無法和STL其他組件搭配(配接器),產生更靈活的變化:

仿函數應當有能力被函數配接器修飾,然後彼此合作形成一個整體。為了可配接仿函數需要定義自己的相應型別(和叠代器的型別的作用是一個含義)。由於STL只使用一元和二元仿函數,所以定義了兩個class:unaru_function和binary_function。這兩個類沒有成員,只有一些型別定義。任何仿函數,只要依個人需求選擇繼承其中一個class,便自動擁有了那些相應型別,也就自動擁有了配接能力。

其次仿函數相對於函數指針有其自身優點:

1、 仿函數是智能型函數

就好比智能指針的行為像指針,其就可看作是一個指針。但是智能指針是定義的一個類對象,所以在具備指針功能的同時也有其他的能力。仿函數的能力也可以超越operator()。因為仿函數可以擁有成員函數和成員變量,這意味著仿函數擁有狀態。另一個好處是可以在執行期初始化它們。

2、 仿函數都有自己的型別

這就是泛型編程編寫仿函數。

3、 仿函數通常比一般函數快

就template的概念而言,由於更多細節在編譯器就已確定,所以通常可能進行更好的最佳化。


Tags: include return 元素

文章來源:


ads
ads

相關文章
ads

相關文章

ad