bind1nd,not1,compose1等用法

binder/not

1-允许为二元仿函数或判断式绑定一个值,从而将那个值固定下来

2-可以绑定第一个或者第二个参数[二元仿函数会变成一元仿函数]。

比如:

bind1st//通过绑定第一个参数,使二元的函数对象转化为一元的函数对象
bind2nd//通过绑定第二个参数,使二元的函数对象转化为一元的函数对象
not1//对一元的函数对象取反
not2//对二元的函数对象取反

例子

  • bind2nd(less<int>(), 5)作用:x<5 绑定第二个参数
  • bind1st(less<int>(), 5)作用:5<x 绑定第一个参数

统计大于等于5的元素个数?

cout<< count_if(lv.begin(), lv.end(),not1(bind2nd(less<int>(), 5)))<< endl;//>=5的个数,一个参数未定

查找!(x>= 1 && x<= 10)的元素位置?

std::list<int>::iterator in_range =std::find_if(L.begin(), L.end(),

                              std::not1( 

compose2(std::logical_and<bool>(),

std::bind2nd(std::greater_equal<int>(), 1),

std::bind2nd(std::less_equal<int>(), 10))));

查找!(x>= 1|| x<= 10)的元素位置?

std::list<int>::iterator in_range =std::find_if(L.begin(), L.end(),

                                            compose2(sstd::not2(std::logical_or<bool>()),

                                           std::bind2nd(std::greater_equal<int>(), 1),

                                         std::bind2nd(std::less_equal<int>(), 10))));

 

由大到小排序?
     sort(lv.begin(), lv.end(), not2(less<int>()) ) ;//not2 两个参数都未定

对每个元素v计算(v+2)*3

     for_each(v.begin(),v.end(),compose1(

                             bind2st(multiplies<int>(),3),

                             bind2st(plus<int>(),2)));    //(v+2)*3

boost库的类似形式boost::bind:

对每个元素v使用v*1.1*0.9【使用boost库函数】

std::transform(

values.begin(),

values.end(),

values.begin(),

boost::bind(

std::multiplies<double>(),0.90,boost::bind<double>(

std::multiplies<double>(),_1,1.10)));

删除元素大于100并且小于1000的元素?

   list<int>::iterator new_end = //x>100 && x<1000
         remove_if(L.begin(),L.end(),  
      compose2(logical_and<bool>(),  
        bind2nd(greater<int>(),100),  
        bind2nd(less<int>(),1000)));  
  L.erase(new_end, L.end()); 

统计大于5并且小于等于10的数的个数?【使用boost库函数】

int count=std::count_if(

ints.begin(),

ints.end(),

boost::bind(

std::logical_and<bool>(),

boost::bind(std::greater<int>(),_1,5),

boost::bind(std::less_equal<int>(),_1,10)));

unary_compose/ binary_compose

compose1//用于把两个一元函数f(x),g(x)组合成f(g(x)) 

compose2//用于把两个二元函数f(x),g(x)组合成f(g(x))  

例子:

angles中的每个元素v,计算-sin(v*pi / 180),并存入sines

std::transform(angles.begin(), angles.end(), sines.begin(),

              compose1(std::negate<double>(),

               compose1(std::ptr_fun(sin),

std::bind2nd(std::multiplies<double>(), pi / 180.))));

计算每个元素x,计算sin(x)/(x +3) 

     double DBL_MIN = 3.0;

  std::transform(L2.begin(), L2.end(), L2.begin(),

               compose2(std::divides<double>(),

                         std::ptr_fun(sin),

std::bind2nd(std::plus<double>(), DBL_MIN)));

logical_and<T>/ logical_or<T> / logical_not<T>
//条件操作,判断两个条件的与/或/非

例子

条件:大于等于1并且小于等于10

compose2(std::logical_and<bool>(),   
std::bind2nd(std::greater_equal<int>(), 1),   
std::bind2nd(std::less_equal<int>(), 10)));

查找等于’’或等于’\0’的字符?

constchar* wptr =    
         std::find_if(str, str + MAXLEN,   
                 compose2(std::logical_or<bool>(),   
                   std::bind2nd(std::equal_to<char>(), ' '),   
                  std::bind2nd(std::equal_to<char>(), '\n')));

select1st<Pair>/select2nd<Pair>用法

//select1st<Pair>,pair或pair相同接口(如map)的类的第一参数   
//select2nd<Pair>,pair或pair相同接口(如map)的类的第二参数   
       std::map<int, double> M;   
       M[1] = 0.3;   
       M[47] = 0.8;   
       M[33] = 0.1;   
       // 输出1 33 47.   
       std::transform(M.begin(), M.end(),    
          std::ostream_iterator<int>(std::cout, " "),   
           __gnu_cxx::select1st<std::map<int,double>::value_type>());   
       std::cout << std::endl;   
       // 输出0.3 0.1 0.8   
      std::transform(M.begin(), M.end(),    
           std::ostream_iterator<double>(std::cout, " "),   
          __gnu_cxx::select2nd<std::map<int, double>::value_type>());

project1st/project2nd

//project1st<Arg1,Arg2>,忽略第二参数   
std::vector<int>v1(10, 137);   
std::vector<char*>v2(10, (char*) 0);   
std::vector<int>result(10);   
std::transform(v1.begin(), v1.end(), v2.begin(),result.begin(),   
__gnu_cxx::project1st<int,char*>());   
assert(std::equal(v1.begin(),v1.end(), result.begin()));

 

//project2nd<Arg1,Arg2>,忽略第一参数   
std::vector<char*>v1(10, (char*) 0);   
std::vector<int>v2(10, 137);   
std::vector<int>result(10);   
std::transform(v1.begin(),v1.end(), v2.begin(), result.begin(),   
           project2nd<char*,int>());   
assert(std::equal(v2.begin(),v2.end(), result.begin()));  

plus<T>/minus<T>/multiplies<T>/divides<T>/modulus<T>

//序列相加/相减/相乘/相除/取模

例子:

//V3 = V1 + V2

const int N = 1000;

std::vector<double> V1(N);

std::vector<double> V2(N); 

std::vector<double> V3(N);

assert(V2.size() >= V1.size() && V3.size() >= V1.size());

std::transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),std::plus<double>());

negate<T>,序列取相反数

 //V2 = -V1  

例子:

每个元素取反?

const int N = 1000;

std::vector<int> V1(N);

std::vector<int> V2(N); 

assert(V2.size() >= V1.size()); 

std::transform(V1.begin(), V1.end(), V2.begin(),std::negate<int>());

equal_to<T> / not_equal_to<T> / less<T> / greater<T> / less_equal<T> / greater_equal<T>

//条件操作,判断是否等于/不等于/小于/大于/小于等于/大于等于某个数

例子

0移到数组最左边的区间?

int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};

const int N = sizeof(A)/sizeof(int); 

std::partition(A, A + N, std::bind2nd(std::equal_to<int>(), 0));

std::copy(A, A + N, std::ostream_iterator<int>(std::cout, " ")); 

std::cout << std::endl;

查找不等于0的元素的位置(或是否存在)?

查找满足条件的位置

 std::list<int>::iterator first_nonzero = std::find_if(L.begin(), L.end(),

std::bind2nd(std::not_equal_to<int>(), 0));

assert(first_nonzero == L.end() || *first_nonzero != 0);

posted on 2020-08-29 19:51  莫水千流  阅读(397)  评论(0编辑  收藏  举报