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 介绍
bind1st和bind2nd函数用于将一个二元函数对象(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());