在绑定参数这一节,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的新特性。