今天翻看STL中的Functional標頭檔,檔案中定義了一些常用的函數對象(顧名思義,就是定義重載()運算子,讓一個類向一個函數一樣去用)。
首先定義了一個結構體來作為其它結構體的基類,實際上這個結構體只是提供了統一的類型名以使其他的類來繼承。
一元結構體模板定於如下:
template<class _A, class _R>
struct unary_function {
typedef _A argument_type;
typedef _R result_type;
};
模板參數的定義應該能夠看出來,其中之一是輸入的參數,另一個是輸出結果。二元的話,就不用說了,只不過比一元的多了一個輸入參數而已:
template<class _A1, class _A2, class _R>
struct binary_function {
typedef _A1 first_argument_type;
typedef _A2 second_argument_type;
typedef _R result_type;
};
下面看看其他的函數對象如何去定義,以greater為例。
template<class _Ty>
struct greater : binary_function<_Ty, _Ty, bool> {
bool operator()(const _Ty& _X, const _Ty& _Y) const
{
return (_X > _Y);
}
};
以STL中的sort為例,首先定義一個數組
int a[5] = {2,4,1,3,5};
sort(&a[0],&a[5]);
輸出結果應該為1,2,3,4,5.
但是如果用函數對象greater來作為sort的第三個參數:
sort(&a[0],&a[5],greater<int>());
那麼輸出結果就變成了5,4,3,2,1.
也就是sort內部的比較方式採用了greater來比較。
為了充分理解函數對象,自訂一個結構體,繼承自binary_function ,用以按照絕對值的大小來排序。
template<class T>
struct AbsoluteLess : public binary_function<T,T,bool>
{
bool operator() (T x ,T y) const
{
return abs(x) > abs(y);
}
};
然後在冒泡排序中使用這個函數對象,
冒泡排序如下:
template<class T,class CompareType>
void Bubble_Sort(T *p,int size,const CompareType& Compare)
{
for (int i=0;i<size;++i)
{
for (int j= i+1;j<size;++j)
{
if(Compare(p[i],p[j]))
{
const T temp = p[i];
p[i] = p[j];
p[j] = temp;
}
}
}
}
測試程式如下:
int main()
{
double a[7] = {-100.77,-40.2,50.4,23.6,67.1,-10.3,11.8};
int size = sizeof(a)/sizeof(double);
Bubble_Sort(a,size,greater<double>());
Display(a,size); //print a
Bubble_Sort(a,size,AbsoluteLess<double>());
Display(a,size);
return 0;
}
輸出結果:
Bubble_Sort(a,size,greater<double>()) :
67.1 50.4 23.6 11.8 -10.3 -40.2 -100.77
Bubble_Sort(a,size,AbsoluteLess<double>()) :
-10.3 11.8 23.6 -40.2 50.4 67.1 -100.77