### 前言
? 在STL中,函數對象也是比較重要的,有時候可以限定STL算法的行為,例如在前面介紹的《[STL](http://blog.csdn.net/chenhanzhun/article/details/39698523)[算法剖析](http://blog.csdn.net/chenhanzhun/article/details/39698523)》中,每個算法基本上都提供了兩個操作版本,其中就有一個版本允許用戶指定函數對象,這樣可以根據用戶的需要對算法進行操作。函數對象是一種具有函數特質的對象,所以可以作為算法的參數。本文介紹的函數對象比較簡單,是基于一元或者二元操作結構的算術類函數對象、關系運算類函數對象、邏輯運算類函數對象。在定義函數對象時,為了使其具有函數行為,則必須重載operator()操作符。本文源碼出自SGI STL中的<stl_function.h>文件。
### 函數對象源碼剖析
~~~
_STL_BEGIN_NAMESPACE
//一元操作結構定義
template <class _Arg, class _Result>
struct unary_function {
typedef _Arg argument_type;//參數類型
typedef _Result result_type;//返回結果類型
};
//二元操作結構定義
template <class _Arg1, class _Arg2, class _Result>
struct binary_function {
typedef _Arg1 first_argument_type;//參數一類型
typedef _Arg2 second_argument_type;//參數二類型
typedef _Result result_type;//返回結果類型
};
//以下是二元操作算術函數對象,繼承二元操作binary_function的結構
/*
加法操作plus<T>,減法操作minus<T>,乘法操作multiplies<T>,除法操作divides<T>,
取模運算modulus<T>,
*/
template <class _Tp>
struct plus : public binary_function<_Tp,_Tp,_Tp> {
_Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; }
};
template <class _Tp>
struct minus : public binary_function<_Tp,_Tp,_Tp> {
_Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; }
};
template <class _Tp>
struct multiplies : public binary_function<_Tp,_Tp,_Tp> {
_Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; }
};
template <class _Tp>
struct divides : public binary_function<_Tp,_Tp,_Tp> {
_Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; }
};
template <class _Tp>
struct modulus : public binary_function<_Tp,_Tp,_Tp>
{
_Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; }
};
//一元操作,繼承一元操作unary_function結構
//負值操作negate<T>
template <class _Tp>
struct negate : public unary_function<_Tp,_Tp>
{
_Tp operator()(const _Tp& __x) const { return -__x; }
};
// identity_element (not part of the C++ standard).
//證同元素:
//以下只提供的兩種證同元素
//加法:任何元素加上0結果都為自身
//乘法:任何元素乘以1結果都為自身
template <class _Tp> inline _Tp identity_element(plus<_Tp>) {
return _Tp(0);
}
template <class _Tp> inline _Tp identity_element(multiplies<_Tp>) {
return _Tp(1);
}
//以下是二元操作關系函數對象,繼承二元操作的結構
/*
返回值的類型是bool型別
equal_to,not_equal_to,greater,less,greater_equal,less_equal,
*/
template <class _Tp>
struct equal_to : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; }
};
template <class _Tp>
struct not_equal_to : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; }
};
template <class _Tp>
struct greater : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; }
};
template <class _Tp>
struct less : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
};
template <class _Tp>
struct greater_equal : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; }
};
template <class _Tp>
struct less_equal : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; }
};
//以下是二元操作邏輯函數對象,繼承二元操作的結構
/*
其中logical_not為一元操作函數
logical_and,logical_or,logical_not
*/
template <class _Tp>
struct logical_and : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; }
};
template <class _Tp>
struct logical_or : public binary_function<_Tp,_Tp,bool>
{
bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; }
};
template <class _Tp>
struct logical_not : public unary_function<_Tp,bool>
{
bool operator()(const _Tp& __x) const { return !__x; }
};
// identity is an extensions: it is not part of the standard.
//證同函數
//任何數值通過此函數后,不會有任何修改。所以返回值類型為const引用
template <class _Tp>
struct _Identity : public unary_function<_Tp,_Tp> {
const _Tp& operator()(const _Tp& __x) const { return __x; }
};
template <class _Tp> struct identity : public _Identity<_Tp> {};
// select1st and select2nd are extensions: they are not part of the standard.
//選擇函數
//版本一:選擇pair元素的第一個參數,忽略第二個參數
template <class _Pair>
struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> {
const typename _Pair::first_type& operator()(const _Pair& __x) const {
return __x.first;
}
};
//版本二:選擇pair元素的第二個參數,忽略第一個參數
template <class _Pair>
struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type>
{
const typename _Pair::second_type& operator()(const _Pair& __x) const {
return __x.second;
}
};
template <class _Pair> struct select1st : public _Select1st<_Pair> {};
template <class _Pair> struct select2nd : public _Select2nd<_Pair> {};
// project1st and project2nd are extensions: they are not part of the standard
//投射函數
//版本一:投射出第一個參數,忽略第二個參數
template <class _Arg1, class _Arg2>
struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> {
_Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; }
};
//版本二:投射出第二個參數,忽略第一個參數
template <class _Arg1, class _Arg2>
struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> {
_Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; }
};
template <class _Arg1, class _Arg2>
struct project1st : public _Project1st<_Arg1, _Arg2> {};
template <class _Arg1, class _Arg2>
struct project2nd : public _Project2nd<_Arg1, _Arg2> {};
~~~
參考資料:
《STL源碼剖析》侯捷
- 前言
- 空間配置器
- Traits編程技術
- STL源碼剖析——迭代器
- 全局函數construct(),destroy(),uninitialized_copy(),uninitialized_fill(),uninitialized_fill_n()
- 序列容器之vector
- list容器的排序算法sort()
- 序列容器之list
- 序列容器之deque
- 容器配接器之stack
- 容器配接器之queue
- 容器配接器之priority_queue
- 最大堆heap
- 單向鏈表slist
- RB-Tree(紅黑樹)
- 關聯容器之set
- stl_pair.h學習
- 關聯容器之map
- 關聯容器之multiset
- 關聯容器之multimap
- 散列表hashtable
- stl_hash_fun.h學習
- 關聯容器之hash_set
- 關聯容器之hash_multiset
- 關聯容器之hash_map
- 關聯容器之hash_multimap
- 數值算法stl_numeric.h
- stl_relops.h學習
- 基本算法stl_algobase.h
- STL算法之set集合算法
- STL算法stl_algo.h
- STL算法之sort排序算法
- STL算法之find查找算法
- STL算法之merge合并算法
- STL算法之remove刪除算法
- STL算法之permutation排列組合
- STL函數對象