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)));
查找等于’’或等于’ ’的字符?
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>(), '
')));
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);