STL源码剖析——STL函数对象

╰半橙微兮° 2022-08-12 20:58 341阅读 0赞

前言

在STL中,函数对象也是比较重要的,有时候可以限定STL算法的行为,例如在前面介绍的《STL算法剖析》中,每个算法基本上都提供了两个操作版本,其中就有一个版本允许用户指定函数对象,这样可以根据用户的需要对算法进行操作。函数对象是一种具有函数特质的对象,所以可以作为算法的参数。本文介绍的函数对象比较简单,是基于一元或者二元操作结构的算术类函数对象、关系运算类函数对象、逻辑运算类函数对象。在定义函数对象时,为了使其具有函数行为,则必须重载operator()操作符。本文源码出自SGI STL中的文件。

函数对象源码剖析

  1. _STL_BEGIN_NAMESPACE
  2. //一元操作结构定义
  3. template <class _Arg, class _Result>
  4. struct unary_function {
  5. typedef _Arg argument_type;//参数类型
  6. typedef _Result result_type;//返回结果类型
  7. };
  8. //二元操作结构定义
  9. template <class _Arg1, class _Arg2, class _Result>
  10. struct binary_function {
  11. typedef _Arg1 first_argument_type;//参数一类型
  12. typedef _Arg2 second_argument_type;//参数二类型
  13. typedef _Result result_type;//返回结果类型
  14. };
  15. //以下是二元操作算术函数对象,继承二元操作binary_function的结构
  16. /*
  17. 加法操作plus<T>,减法操作minus<T>,乘法操作multiplies<T>,除法操作divides<T>,
  18. 取模运算modulus<T>,
  19. */
  20. template <class _Tp>
  21. struct plus : public binary_function<_Tp,_Tp,_Tp> {
  22. _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; }
  23. };
  24. template <class _Tp>
  25. struct minus : public binary_function<_Tp,_Tp,_Tp> {
  26. _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; }
  27. };
  28. template <class _Tp>
  29. struct multiplies : public binary_function<_Tp,_Tp,_Tp> {
  30. _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; }
  31. };
  32. template <class _Tp>
  33. struct divides : public binary_function<_Tp,_Tp,_Tp> {
  34. _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; }
  35. };
  36. template <class _Tp>
  37. struct modulus : public binary_function<_Tp,_Tp,_Tp>
  38. {
  39. _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; }
  40. };
  41. //一元操作,继承一元操作unary_function结构
  42. //负值操作negate<T>
  43. template <class _Tp>
  44. struct negate : public unary_function<_Tp,_Tp>
  45. {
  46. _Tp operator()(const _Tp& __x) const { return -__x; }
  47. };
  48. // identity_element (not part of the C++ standard).
  49. //证同元素:
  50. //以下只提供的两种证同元素
  51. //加法:任何元素加上0结果都为自身
  52. //乘法:任何元素乘以1结果都为自身
  53. template <class _Tp> inline _Tp identity_element(plus<_Tp>) {
  54. return _Tp(0);
  55. }
  56. template <class _Tp> inline _Tp identity_element(multiplies<_Tp>) {
  57. return _Tp(1);
  58. }
  59. //以下是二元操作关系函数对象,继承二元操作的结构
  60. /*
  61. 返回值的类型是bool型别
  62. equal_to,not_equal_to,greater,less,greater_equal,less_equal,
  63. */
  64. template <class _Tp>
  65. struct equal_to : public binary_function<_Tp,_Tp,bool>
  66. {
  67. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; }
  68. };
  69. template <class _Tp>
  70. struct not_equal_to : public binary_function<_Tp,_Tp,bool>
  71. {
  72. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; }
  73. };
  74. template <class _Tp>
  75. struct greater : public binary_function<_Tp,_Tp,bool>
  76. {
  77. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; }
  78. };
  79. template <class _Tp>
  80. struct less : public binary_function<_Tp,_Tp,bool>
  81. {
  82. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; }
  83. };
  84. template <class _Tp>
  85. struct greater_equal : public binary_function<_Tp,_Tp,bool>
  86. {
  87. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; }
  88. };
  89. template <class _Tp>
  90. struct less_equal : public binary_function<_Tp,_Tp,bool>
  91. {
  92. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; }
  93. };
  94. //以下是二元操作逻辑函数对象,继承二元操作的结构
  95. /*
  96. 其中logical_not为一元操作函数
  97. logical_and,logical_or,logical_not
  98. */
  99. template <class _Tp>
  100. struct logical_and : public binary_function<_Tp,_Tp,bool>
  101. {
  102. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; }
  103. };
  104. template <class _Tp>
  105. struct logical_or : public binary_function<_Tp,_Tp,bool>
  106. {
  107. bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; }
  108. };
  109. template <class _Tp>
  110. struct logical_not : public unary_function<_Tp,bool>
  111. {
  112. bool operator()(const _Tp& __x) const { return !__x; }
  113. };
  114. // identity is an extensions: it is not part of the standard.
  115. //证同函数
  116. //任何数值通过此函数后,不会有任何修改。所以返回值类型为const引用
  117. template <class _Tp>
  118. struct _Identity : public unary_function<_Tp,_Tp> {
  119. const _Tp& operator()(const _Tp& __x) const { return __x; }
  120. };
  121. template <class _Tp> struct identity : public _Identity<_Tp> {};
  122. // select1st and select2nd are extensions: they are not part of the standard.
  123. //选择函数
  124. //版本一:选择pair元素的第一个参数,忽略第二个参数
  125. template <class _Pair>
  126. struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> {
  127. const typename _Pair::first_type& operator()(const _Pair& __x) const {
  128. return __x.first;
  129. }
  130. };
  131. //版本二:选择pair元素的第二个参数,忽略第一个参数
  132. template <class _Pair>
  133. struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type>
  134. {
  135. const typename _Pair::second_type& operator()(const _Pair& __x) const {
  136. return __x.second;
  137. }
  138. };
  139. template <class _Pair> struct select1st : public _Select1st<_Pair> {};
  140. template <class _Pair> struct select2nd : public _Select2nd<_Pair> {};
  141. // project1st and project2nd are extensions: they are not part of the standard
  142. //投射函数
  143. //版本一:投射出第一个参数,忽略第二个参数
  144. template <class _Arg1, class _Arg2>
  145. struct _Project1st : public binary_function<_Arg1, _Arg2, _Arg1> {
  146. _Arg1 operator()(const _Arg1& __x, const _Arg2&) const { return __x; }
  147. };
  148. //版本二:投射出第二个参数,忽略第一个参数
  149. template <class _Arg1, class _Arg2>
  150. struct _Project2nd : public binary_function<_Arg1, _Arg2, _Arg2> {
  151. _Arg2 operator()(const _Arg1&, const _Arg2& __y) const { return __y; }
  152. };
  153. template <class _Arg1, class _Arg2>
  154. struct project1st : public _Project1st<_Arg1, _Arg2> {};
  155. template <class _Arg1, class _Arg2>
  156. struct project2nd : public _Project2nd<_Arg1, _Arg2> {};

参考资料:

《STL源码剖析》侯捷

发表评论

表情:
评论列表 (有 0 条评论,341人围观)

还没有评论,来说两句吧...

相关阅读

    相关 STL剖析--vector

    vector容器概述       vector的数据安排以及操作方式,与array非常相似。两者的唯一区别在于空间的运用的灵活性。array是静态空间,一旦配置了就不能改变

    相关 STL剖析1

    stl概论 stl以抽象概念为主题而非以实际类为主的结构,形成了一个严谨的接口标准。在此接口之下,任何组件都有最大的独立性,并以所谓迭代器胶合起来,或以所谓配接器互相配接,或