not1|not2和bind1st|bind2nd详解

1. not1 | not2

1.1 介绍

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

1.2 源码

//TEMPLATE FUNCTION not1
template<class _Fn1> inline
constexpr unary_negate<_Fn1> not1(const _Fn1& _Func)
{	//return a unary_negate functor adapter
	return (unary_negate<_Fn1>(_Func));
}

//TEMPLATE FUNCTION not2
template<class _Fn2> inline
constexpr binary_negate<_Fn2> not2(const _Fn2& _Func)
{	//return a binary_negate functor adapter
    return (binary_negate<_Fn2>(_Func));
}

//TEMPLATE CLASS binary_negate
template<class _Fn2>
class binary_negate
{	// functor adapter !_Func(left, right)
public:
	typedef typename _Fn2::first_argument_type first_argument_type;
	typedef typename _Fn2::second_argument_type second_argument_type;
	typedef bool result_type;

	constexpr explicit binary_negate(const _Fn2& _Func)
		: _Functor(_Func)
		{	// construct from functor
		}

	constexpr bool operator()(const first_argument_type& _Left,
		const second_argument_type& _Right) const
		{	// apply functor to operands
		return (!_Functor(_Left, _Right));
		}

private:
	_Fn2 _Functor;	// the functor to apply
};

1.3 例子

// not1 example
#include <iostream>     // std::cout
#include <functional>   // std::not1
#include <algorithm>    // std::count_if

struct IsOdd {
  bool operator() (const int& x) const {return x%2==1;}
  typedef int argument_type;
};

int main () {
  int values[] = {1,2,3,4,5};
  int cx = std::count_if (values, values+5, std::not1(IsOdd()));
  std::cout << "There are " << cx << " elements with even values.\n";
  return 0;
}
// not2 example
#include <iostream>     // std::cout
#include <functional>   // std::not2, std::equal_to
#include <algorithm>    // std::mismatch
#include <utility>      // std::pair

int main () {
  int foo[] = {10,20,30,40,50};
  int bar[] = {0,15,30,45,60};
  std::pair<int*,int*> firstmatch,firstmismatch;
  firstmismatch = std::mismatch (foo, foo+5, bar, std::equal_to<int>());
  firstmatch = std::mismatch (foo, foo+5, bar, std::not2(std::equal_to<int>()));
  std::cout << "First mismatch in bar is " << *firstmismatch.second << '\n';
  std::cout << "First match in bar is " << *firstmatch.second << '\n';
  return 0;
}

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 源码

//TEMPLATE CLASS binder1st
template<class _Fn2>
class binder1st
	: public unary_function<typename _Fn2::second_argument_type,
		typename _Fn2::result_type>
{	//functor adapter _Func(stored, right)
public:
	typedef unary_function<typename _Fn2::second_argument_type,
		typename _Fn2::result_type> _Base;
	typedef typename _Base::argument_type argument_type;
	typedef typename _Base::result_type result_type;

	binder1st(const _Fn2& _Func,
		const typename _Fn2::first_argument_type& _Left)
		: op(_Func), value(_Left)
		{	// construct from functor and left operand
		}

	result_type operator()(const argument_type& _Right) const
		{	// apply functor to operands
		return (op(value, _Right));
		}

	result_type operator()(argument_type& _Right) const
		{	// apply functor to operands
		return (op(value, _Right));
		}

protected:
	_Fn2 op;	// the functor to apply
	typename _Fn2::first_argument_type value;	// the left operand
};

//TEMPLATE FUNCTION bind1st
template<class _Fn2,
	class _Ty> inline
binder1st<_Fn2> bind1st(const _Fn2& _Func, const _Ty& _Left)
{	// return a binder1st functor adapter
	typename _Fn2::first_argument_type _Val(_Left);
	return (binder1st<_Fn2>(_Func, _Val));
}
//TEMPLATE CLASS binder2nd
template<class _Fn2>
class binder2nd
	: public unary_function<typename _Fn2::first_argument_type,
		typename _Fn2::result_type>
{	//functor adapter _Func(left, stored)
public:
	typedef unary_function<typename _Fn2::first_argument_type,
		typename _Fn2::result_type> _Base;
	typedef typename _Base::argument_type argument_type;
	typedef typename _Base::result_type result_type;

	binder2nd(const _Fn2& _Func,
		const typename _Fn2::second_argument_type& _Right)
		: op(_Func), value(_Right)
		{	// construct from functor and right operand
		}

	result_type operator()(const argument_type& _Left) const
		{	// apply functor to operands
		return (op(_Left, value));
		}

	result_type operator()(argument_type& _Left) const
		{	// apply functor to operands
		return (op(_Left, value));
		}

protected:
	_Fn2 op;	// the functor to apply
	typename _Fn2::second_argument_type value;	// the right operand
};

//TEMPLATE FUNCTION bind2nd
template<class _Fn2,
	class _Ty> inline
binder2nd<_Fn2> bind2nd(const _Fn2& _Func, const _Ty& _Right)
{	//return a binder2nd functor adapter
	typename _Fn2::second_argument_type _Val(_Right);
	return (binder2nd<_Fn2>(_Func, _Val));
}

2.3 例子

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

int a[] = {1, 2, 100, 200};

std::vector< int> arr(a, a + 4);

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

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

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

         移除所有大于100的元素:

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

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

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

         移除所有等于100的元素:

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小胖七少爷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值