• 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的新特性。

  • 相关阅读:
    Android 9.0版本及以上开发时遇到的一些版本问题
    【经典】半平面交求解方程组——poj1755
    【模板】凸包向内推进求不严格的半平面交——poj3384
    二分+半平面交——poj1279
    AngularJS 启程
    全栈工程师--这才是真正的从入门到跑路
    数据库学习路线-从入门到入土
    java学习路线-从入门到入土
    前端路线-从入门到入土
    前端小练习
  • 原文地址:https://www.cnblogs.com/VCctor/p/5100685.html
Copyright © 2020-2023  润新知