• not1|not2和bind1st|bind2nd详解


    1. not1 | not2

    1.1 介绍

             not1是构造一个与谓词结果相反一元函数对象not2是构造一个与谓词结果相反二元函数对象

    1.2 源码

    1. //TEMPLATE FUNCTION not1
    2. template<class _Fn1> inline
    3. constexpr unary_negate<_Fn1> not1(const _Fn1& _Func)
    4. { //return a unary_negate functor adapter
    5. return (unary_negate<_Fn1>(_Func));
    6. }
    7. //TEMPLATE FUNCTION not2
    8. template<class _Fn2> inline
    9. constexpr binary_negate<_Fn2> not2(const _Fn2& _Func)
    10. { //return a binary_negate functor adapter
    11. return (binary_negate<_Fn2>(_Func));
    12. }
    13. //TEMPLATE CLASS binary_negate
    14. template<class _Fn2>
    15. class binary_negate
    16. { // functor adapter !_Func(left, right)
    17. public:
    18. typedef typename _Fn2::first_argument_type first_argument_type;
    19. typedef typename _Fn2::second_argument_type second_argument_type;
    20. typedef bool result_type;
    21. constexpr explicit binary_negate(const _Fn2& _Func)
    22. : _Functor(_Func)
    23. { // construct from functor
    24. }
    25. constexpr bool operator()(const first_argument_type& _Left,
    26. const second_argument_type& _Right) const
    27. { // apply functor to operands
    28. return (!_Functor(_Left, _Right));
    29. }
    30. private:
    31. _Fn2 _Functor; // the functor to apply
    32. };

    1.3 例子

    1. // not1 example
    2. #include // std::cout
    3. #include // std::not1
    4. #include // std::count_if
    5. struct IsOdd {
    6. bool operator() (const int& x) const {return x%2==1;}
    7. typedef int argument_type;
    8. };
    9. int main () {
    10. int values[] = {1,2,3,4,5};
    11. int cx = std::count_if (values, values+5, std::not1(IsOdd()));
    12. std::cout << "There are " << cx << " elements with even values.\n";
    13. return 0;
    14. }
    1. // not2 example
    2. #include // std::cout
    3. #include // std::not2, std::equal_to
    4. #include // std::mismatch
    5. #include // std::pair
    6. int main () {
    7. int foo[] = {10,20,30,40,50};
    8. int bar[] = {0,15,30,45,60};
    9. std::pair<int*,int*> firstmatch,firstmismatch;
    10. firstmismatch = std::mismatch (foo, foo+5, bar, std::equal_to<int>());
    11. firstmatch = std::mismatch (foo, foo+5, bar, std::not2(std::equal_to<int>()));
    12. std::cout << "First mismatch in bar is " << *firstmismatch.second << '\n';
    13. std::cout << "First match in bar is " << *firstmatch.second << '\n';
    14. return 0;
    15. }

    2. bind1st | bind2nd

    2.1 介绍

            bind1stbind2nd函数用于将一个二元函数对象(binary functor,bf)转换成一元函数对象(unary functor,uf)。为了达到这个目的,它们需要两个参数:要转换的bf一个值(v)。

            

    • f = std::bind2nd( functor, k); 'f( x)'等价于'functor( x, k)'

            使用bind2nd则对应的表达式是x > k ,x < k,这里的是把k作为比较表达式的第二个参数。

    • f = std::bind1st( functor, k); 'f( x)'等价于'functor( k, x)'

             如用bind1st则对应的表达式是 k > x,k < x,也就是把k作为比较表达式的第一个参数。

    2.2 源码

    1. //TEMPLATE CLASS binder1st
    2. template<class _Fn2>
    3. class binder1st
    4. : public unary_function<typename _Fn2::second_argument_type,
    5. typename _Fn2::result_type>
    6. { //functor adapter _Func(stored, right)
    7. public:
    8. typedef unary_function<typename _Fn2::second_argument_type,
    9. typename _Fn2::result_type> _Base;
    10. typedef typename _Base::argument_type argument_type;
    11. typedef typename _Base::result_type result_type;
    12. binder1st(const _Fn2& _Func,
    13. const typename _Fn2::first_argument_type& _Left)
    14. : op(_Func), value(_Left)
    15. { // construct from functor and left operand
    16. }
    17. result_type operator()(const argument_type& _Right) const
    18. { // apply functor to operands
    19. return (op(value, _Right));
    20. }
    21. result_type operator()(argument_type& _Right) const
    22. { // apply functor to operands
    23. return (op(value, _Right));
    24. }
    25. protected:
    26. _Fn2 op; // the functor to apply
    27. typename _Fn2::first_argument_type value; // the left operand
    28. };
    29. //TEMPLATE FUNCTION bind1st
    30. template<class _Fn2,
    31. class _Ty> inline
    32. binder1st<_Fn2> bind1st(const _Fn2& _Func, const _Ty& _Left)
    33. { // return a binder1st functor adapter
    34. typename _Fn2::first_argument_type _Val(_Left);
    35. return (binder1st<_Fn2>(_Func, _Val));
    36. }
    1. //TEMPLATE CLASS binder2nd
    2. template<class _Fn2>
    3. class binder2nd
    4. : public unary_function<typename _Fn2::first_argument_type,
    5. typename _Fn2::result_type>
    6. { //functor adapter _Func(left, stored)
    7. public:
    8. typedef unary_function<typename _Fn2::first_argument_type,
    9. typename _Fn2::result_type> _Base;
    10. typedef typename _Base::argument_type argument_type;
    11. typedef typename _Base::result_type result_type;
    12. binder2nd(const _Fn2& _Func,
    13. const typename _Fn2::second_argument_type& _Right)
    14. : op(_Func), value(_Right)
    15. { // construct from functor and right operand
    16. }
    17. result_type operator()(const argument_type& _Left) const
    18. { // apply functor to operands
    19. return (op(_Left, value));
    20. }
    21. result_type operator()(argument_type& _Left) const
    22. { // apply functor to operands
    23. return (op(_Left, value));
    24. }
    25. protected:
    26. _Fn2 op; // the functor to apply
    27. typename _Fn2::second_argument_type value; // the right operand
    28. };
    29. //TEMPLATE FUNCTION bind2nd
    30. template<class _Fn2,
    31. class _Ty> inline
    32. binder2nd<_Fn2> bind2nd(const _Fn2& _Func, const _Ty& _Right)
    33. { //return a binder2nd functor adapter
    34. typename _Fn2::second_argument_type _Val(_Right);
    35. return (binder2nd<_Fn2>(_Func, _Val));
    36. }

    2.3 例子

            使用bind2nd,则是移除所有小于100的元素:

    1. int a[] = {1, 2, 100, 200};
    2. std::vector< int> arr(a, a + 4);
    3. //移除所有小于100的元素
    4. //std::bind2nd( std::less(), 100)在这里相当于arr.value < 100
    5. arr.erase( std::remove_if( arr.begin(), arr.end(),std::bind2nd( std::less<int>(), 100)), arr.end());

            使用bind1st,则是移除所有大于100的元素:

    1. //移除所有大于100的元素
    2. //std::bind1st(std::less(), 100)在这里相当于100 < arr.value
    3. arr.erase( std::remove_if( arr.begin(), arr.end(),std::bind1st( std::less<int>(), 100)), arr.end());

             移除所有大于100的元素:

    1. //移除所有大于100的元素
    2. //std::bind2nd(std::greater< int>(), 100))在这里相当于arr.value > 100
    3. arr.erase( std::remove_if( arr.begin(), arr.end(),std::bind2nd( std::greater< int>(), 100)), arr.end());

            移除所有小于等于100的元素:

    1. //移除所有小于等于100的元素
    2. arr.erase( std::remove_if( arr.begin(), arr.end(),std::not1(std::bind2nd( std::greater< int>(), 100))), arr.end());

             移除所有等于100的元素:

    1. //移除所有等于100的元素
    2. arr.erase( std::remove_if( arr.begin(), arr.end(),std::bind2nd( std::equal_to< int>(), 100)), arr.end());

  • 相关阅读:
    软件测试下的AI之路(3)
    Python Flask框架学习教程
    C++——模板初阶
    开发者,云原生数据库是未来吗?
    聚华祥科技: 商品怎么进行分类
    Solidty基础篇2-映射、msg、require、继承、引入、存储变量、函数内部和外部可见性
    Docker容器与虚拟化技术:DaoCloud账户注册
    年年出妖事,一例由JSON解析导致的"薛定谔BUG"排查过程记录
    node项目调试
    Selenium入门
  • 原文地址:https://blog.csdn.net/weixin_43712770/article/details/126027993