动机
老是用lambda表达式,也不行呀,得让普通函数也能适应一下标准库算法。
形式
auto newCallable = bind(callable, arg_list); //arg_list是给callable的参数
用法
普通函数如下,传不进find_if函数。
bool check_size(const string &s1, const int &sz)
{
return s1.size()>= sz;
}
bind改良一下
auto check = bind(check_size, _1, 6); //
解释:_1是check的第一个参数,传给check_size的第一个参数,6是固定值,传给check_size的第二个参数。
这样find_if就能用了
find_if(words.begin(),words.end(), check);
find_if(words.begin(),words.end(), bind(check_size, _1, 6));
find_if调用机理
先创建一个匿名对象,然后匿名对象把参数传给check_size。这里匿名对象的参数类型不用定义了,应该是自动推断的。
占位符
占位符指的是newCallable的参数,传进callable的参数列表。
auto g = bind(f, a, b, _2, c, _1);
调用g(_1,_2)等价于 f(a, b, _2, c, _1)。
一个妙用
sort(words,begin(), words,end(), isShorter);
sort(words,begin(), words,end(), bind(isShorter, _2, _1)); //反着排序
bind拷贝其参数
一个不好的地方时bind对传进来的参数拷贝。
ostream &pint(ostream & os, const string &s, char c)
{
return os<<s<<c;
}
for_each(words.begin(), words,end(), bind(print, os, _1, ' ')); //xxx,os要被拷贝了,但不支持拷贝
for_each(words.begin(), words,end(), bind(print, ref(os), _1, ' ')); //ref()返回可拷贝对象,对象类型应该不是os的类型,只是包装os成一个新对象。
解释:bind是一个函数,要拷贝传进来的参数,当然再调用print时,print就不用拷贝了。