C++primer--lambda表達式-參數綁定之bind

在綁定參數這一節,C++11有了新的特性,由於舊版本的綁定參數的語言特性限制更多,也更復雜,所以標準庫定義了兩個分別名爲bind1st和bind2nd的函數,類似bind,這兩個函數接受一個函數作爲參數,生成一個新的可調用對象,該對象調用給定函數,並將綁定的參數傳遞給他。但是這些函數分別只能綁定第一個或第二個參數。
由於這些函數侷限太強,在新標準中已被棄用(deprecated).所謂被起用的特性就是在新版本中不在支持的特性。新的bind應該使用bind。
#include<iostream>
#include <vector>
#include <algorithm>
#include<numeric>
#include<fstream>
#include<functional>
#include<string>
#include<ostream>
using namespace std;
using namespace std::placeholders;
inline void output_date(const vector<string>&s)
{
    for (auto i = s.begin(); i != s.end(); i++)
    {
        cout << *i << "  ";
    }
    cout << endl;

}
bool check_size(const string &s, string::size_type sz)
{
    return s.size() > sz;
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
    output_date(words);
    auto bc = count_if(words.begin(), words.end(), bind(check_size, _1, sz));
}
int main(int argc, char **argv)
{
    ifstream in(argv[1]);
    if (!in)
    {
        cerr << "can't open the file";
        exit(1);
    }
    vector<string>words;
    string word;
    while (in >> word)
        words.push_back(word);
    biggies(words, 6);

}

用函數替代lambda的方法

這個表示函數代替lambda的方法,其實也就是兩者的區別。當lambda不捕獲局部變量時,用函數替代它是很容易的,但是當lambda捕獲局部變量時就不是那麼簡單了,因爲在這種情況下,算法要求可調用的對象接受的參數個數少於函數所需的參數個數,lambda通過捕獲的局部變量來彌補這個差距,而普通函數是做不到這些的。還好標準庫提供了bind函數。

對於bind()接受幾個參數而言?

由於bind是可變參數的,它接受的第一個參數是一個可調用的函數對象,即實際工作函數A,返回供算法使用的新的可調用對象B。若A接受X個參數,則bind的參數個數應該是X+1,就是除了A外,其他參數應該一一對應A所接受的參數。這些參數中有一部分來在於B(_n),另外一些來自於所處函數的局部變量。

關於lambda表達式
主要代碼如下

#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<string>
#include<fstream>
#include <functional>
using namespace std;
using namespace std::placeholders;

void output_date(const vector<string>&s)
{
    for (auto i = s.begin(); i != s.end(); i++)
    {
        cout << *i << "  ";
    }
    cout << endl;

}
void output_date(const vector<int>&s)
{
    for (auto i = s.begin(); i != s.end(); i++)
    {
        cout << *i << "  ";
    }
    cout << endl;

}
void output_date(const vector<string>::iterator beg,const vector<string>::iterator iter)
{
    for (auto i = beg; i != iter; i++)
    {
        cout << *i << "  ";
    }
    cout << endl;

}
bool isShorter(const string &s1, const string &s2)
{
    return s1.size() < s2.size();
}
bool isEnoughLEngth(const string &s1)
{
    return s1.size() > 5;
}
/////////////////////////////lambda表達式函數///////////////

void add(int az)
{
    auto sumint = [az](int b) { return az + b; };
    cout << sumint(1)<<"  ";
}
void biggies(vector<string>&words, vector<string>::size_type sz)
{
    stable_sort(words.begin(),words.end(),
        [sz](const string &s1, const string &s2) { return s1.size() < s2.size(); });
    for_each(words.begin(), words.end(), [](const string &s) { cout << s << endl; });

}

void bigge(vector<string> &words, vector<string>::size_type sz,ostream &os=cout,char c=' ')
{   
    //os隱式捕獲採用引用捕獲方式。c顯式捕獲,值捕獲方式
    for_each(words.begin(), words.end(),
        [&, c](const string &s) { os << s << c; });
    for_each(words.begin(), words.end(),
        [=, &os](const string &s) { os << s << c; });
}
ostream &print(ostream&os, const string &s, char c)
{
    return os << s << c;
}
int main(int argc, char**argv)
{
    vector<string >vec{ "china", "chinese", "word", "hello", "dear", "marry", "hurt" };
    stable_sort(vec.begin(), vec.end(), isShorter);//按照字典序排列,首先用長度大小排列,當長度相等則使用字典序。
    output_date(vec);
    auto iter = partition(vec.begin(), vec.end(), isEnoughLEngth);
    output_date(vec.begin(), iter);
    auto countnum = count_if(vec.begin(), vec.end(),
        [](const string &s) { return s.size() > 5; });
    cout <<"vec中有"<< countnum <<"個超過5的單詞"<< endl;
    stable_sort(vec.begin(), vec.end(), 
        [](const string &s1, const string&s2)
        {return s1.size() > 5;});//典型的lanbda閉包表達式關係,內置的函數體
    auto sum = [](int a, int b) { return a + b; };
    cout << sum(6, 5) << endl;;
    add(6);
    //當以引用捕獲一個lambda變量時,必須保證在閉包執行時變量是存在的
    vector<int>veint{ 1, -2, 3, 67, 32, -6, -32, -32, 6, -3, -523, -45, -5334, -3531, 632, 45, 32, 634, 6, 23, 523 };
    transform(veint.begin(), veint.end(), veint.begin(),
        [](int i)->int { if (i < 0) return -i; else return i; });
    //書上說在這裏必須要有尾置返回類型、但是測試時不需要尾置返回類型也可以編譯通過,應該是優化後的結果吧
    output_date(veint);
    //auto wc = find_if(vec.begin(),vec.end(),bind(_1,add));

    system("pause");
}

對於lambda表達式,在函數引用上還是相當方便的,這是C++11的新特性。

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