bind解救普通函數

動機

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章