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

你可能感兴趣的:(C++,bind,迭代器,lambda,泛型算法)