動機
老是用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就不用拷貝了。