对于那种只在一两个地方使用的简单操作,lambda表达式是最有用的。 如果我们需要在很多地方使用相同的操作,通常应该定义一个函数,而不是多次编写相同的lambda表达式。 类似的,如果一个操作需要很多语句才能完成,通常使用函数更好 如果lambda的捕获列表为空,通常可以用函数来代替它。 但是,对应捕获局部变量的lambda,用函数来替换它就不是那么容易了。
vector<string> v = { "ww","www","wwww","wwwww" };
int sz =3;
auto ret=find_if(v.begin(), v.end(), [sz](string s) {return s.size() > sz; });
cout << *ret << endl;
bool check_size(const string& s, string::size_type sz)
{
return s.size() > sz;
}
为了用check_size来代替lambda,如何解决一元谓词接受一个参数的问题呢?
调用bind的一般形式为:
auto newCallable=bind(callable,arg_list);
绑定check_size的sz参数
using std::placeholders::_1;
//check6是一个可调用对象,接收一个string类型的参数
//并用此string和值6来调用check_size
auto check6 = bind(check_size,_1, 6);
string s = "hello";
bool b1 = check6(s);//check6(s)会调用check_size(s,6)
auto ret=find_if(v.begin(), v.end(), [sz](string s) {return s.size() > sz; });
vector<string> v = { "ww","www","wwww","wwwww" };
int sz =3;
auto ret=find_if(v.begin(), v.end(), bind(check_size,_1,sz));
cout << *ret << endl;
使用placeholders名字
using std::placeholders::_1;
using namespace namespace_name;
using namespace placeholders;
bind的参数
void f(int a, int b, int c, int d, int e){}
void test()
{
//g是一个有两个参数的可调用对象
int a = 0, b = 0, c = 0;
auto g = bind(f, a, b, _2, c, _1);
}
g(_1,_2)
映射为
f(a,b,_2,c,_1)
f(a,b,y,c,x)
用bind重排参数顺序
#include <iostream>
#include<vector>
#include<string>
#include<functional>
#include<algorithm>
using namespace std;
using namespace placeholders;
bool isShorter(string & s1,string& s2)
{
return s1.size()<s2.size();
}
void test()
{
vector<string> v = {"www", "wwww","ww","wwwww" };
cout << "未排序前:" << endl;
for_each(v.begin(), v.end(), [](string& s) {cout << s << " "; });
cout << endl;
cout << "按单词长度由短到长排序" << endl;
sort(v.begin(), v.end(), isShorter);
for_each(v.begin(), v.end(), [](string& s) {cout << s << " "; });
cout << endl;
cout << "按单词长度由长到短排序" << endl;
sort(v.begin(), v.end(), bind(isShorter, _2, _1));
for_each(v.begin(), v.end(), [](string& s) {cout << s << " "; });
cout << endl;
}
int main()
{
test();
system("pause");
return 0;
}
绑定引用参数
vector<string> v = {"www", "wwww","ww","wwwww" };
ostream &os=cout;
char c =' ';
for_each(v.begin(), v.end(), [&os, c](string& s) {cout << s << c; });
ostream& print(ostream& os, const string& s, char c)
{
return os << s << c;
}
//错误:不能拷贝os
for_each(v.begin(), v.end(),bind(print,os,_1,c));
vector<string> v = {"www", "wwww","ww","wwwww" };
ostream &os=cout;
char c =' ';
for_each(v.begin(), v.end(),bind(print,ref(os),_1,c));
注意:
标准库中定义了两个分别为bindlst和bind2nd的函数。 与bind类似,这两个函数接收一个函数做参数,生成一个可调用对象,该对象调用给定函数,并将绑定参数传递给它。 但是,这些函数分别只能绑定第一个或者第二个参数。 由于这些函数局限太强,在新标准库中已经被弃用。 新的c++程序应该使用bind