谓词,lambda表达式和bind

来源:互联网 发布:windows7安装sqlserver 编辑:程序博客网 时间:2024/06/05 02:42


  谓词是一个可调用的表达式,用于返回一个可以做条件的值,分为一元谓词(只接受一个参数)和二元谓词(接收两个参数),例如

bool isShorter(const string& s1, const string& s2){return s1.size() < s2.size();}vector<string> vecStr1 = { "abc","ab","abcd","adwss" };stable_sort(vecStr1.begin(), vecStr1.end(), isShorter);
       其中的isShorter就是一个二元谓词,而stable_sort则根据谓词返回的bool值进行后续操作。但有的时候,需要接受更多的参数,就可以使用lambda表达式,它是可以理解为一个未命名的内联函数,在那种只需要调用一两次的时候,使用lambda表达式可以避免费神去命名一个函数,此外,它可以捕获并使用自身函数体之外的变量,形式如下:
[capture list] (parameter list) -> return type{function body},capturelist(捕获列表): lambda把局部变量包含在这个列表中,之后就可以在自身的函数体中使用这些变量;我们可以忽略参数列表和返回类型,但必须永远包含捕获列表和函数体。下面给一个示例
void biggies(vector<string>& words, vector<string>::size_type sz){auto wc = partition(words.begin(), words.end(), [sz](const string& a) {return a.size() > sz; });for (; wc != words.begin(); wc--)cout << *(wc - 1) << " ";cout << endl;}
     这里lambda把局部变量sz包含在捕获列表中,后面的函数体才能使用它,否则会报错。
       尽量避免捕获引用或指针,真的需要使用时,就需要确保执行lambda时,绑定引用或指针的对象仍然存在,存储的内容仍然是我们想要的。
       不捕获变量的lambda我们可以很容易的用一个函数替代,捕获变量的lambda用bind函数也可以替代,bind函数的一般形式是:auto newCallable=bind(callable,_m,…,_n);bind函数接受一个可调用对象callable,然后生成一个新的可调用对象newCallable,_m,…,_n代表newCallable的第m个和第n个参数,例如
bool check_size(const string &s, string::size_type sz){return s.size() >= sz;}void biggies(vector<string> &words, string::size_type sz){output_words(words);auto count = count_if(words.begin(), words.end(), bind(check_size, _1, sz));cout << "长度大于等于" << sz << "的单词个数为:" << count << endl;}
     这里调用count_if的时候,bind接受check_size生成一个新的函数,这里暂时命名为A(s),count_if把一个string传递给s,s作为A的第一个参数,对应_1,传递给check_size(_1,sz),也就是check_size(s,sz),它返回的bool值作为count_if计数依据。
       lambda的运行速度比bind快,更加简洁易懂,不过利用bind函数还可以改变一些已有函数的参数位置,比如int f(a,b,c,d,e),auto f1=bind(f,a,b,_2,d,_1),使用f1(c,e)就可以得到f(a,b,e,d,c)。
     









1 0
原创粉丝点击