C++primer--lambda表达式-参数绑定之bind

来源:互联网 发布:apache是干什么用的 编辑:程序博客网 时间:2024/05/19 15:39
在绑定参数这一节,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的新特性。

0 0