很多算法都会比较输入序列中的元素。默认情况下,这类算法使用元素类型的<或者==运算符来完成比较。标准库还为这些算法定
义了额外的版本,允许我们提供自己定义的的操作来代替默认运算符。
以sort函数为例,默认使用<来进行比较,元素按照从小到大排序。
sort函数的第二个版本接受第三个参数,此参数是一个谓词。
谓词
谓词是一个可调用表达式,其返回结果是一个能用作条件的值。
标准库算法所使用的谓词分为两类:一元谓词(只接受单一参数)和二元谓词(有两个参数)。
接受谓词参数的算法对输入序列中的元素调用谓词。因此,元素类型必须能转换为谓词的参数类型。
对于sort函数,其谓词的操作必须能够在输入序列中所有可能的元素值上定义一个一致的序。
若想从大到小排序,定义一个比较函数
bool isBigger(int &a,int &b)
{
return a>b;
}
若想将一个vector<string>中的元素长度进行排序。
bool isShorter(const string &s1,const string &s2)
{
return s1.size()<s2.size();
}
注意:
若在类中使用sort函数调用比较函数,最好将函数声明为static或者将函数设置为全局函数,从而避免出现以下错误。
reference to non - static member function must be call
lambda表达式
算法接受的一元谓词还是二元谓词,我们传递给算法的谓词必须严格接受一个或两个参数。但是,有时我们希望进行的操作需要
更多的参数,超出了算法对谓词的严格限制。
一个lambda表达式与任何函数类似,具有一个返回类型,一个参数列表和一个函数体。但与函数不同,lambda可能定义在函数内
部。
一个lambda表达式的形式:
[capture list](parameter list) ->return type{function body}
capture list 捕获列表是一个lambda所在函数中定义的局部变量的列表(通常为空);
return type、parameter和function body与任何普通函数一样,分别表示返回类型、参数列表和函数体。
但是,与普通函数不同的是,lambda必须使用尾置返回来指定返回类型。
我们可以忽略参数列表和返回类型,但是必须包含捕获列表和函数体。
auto f=[] {return 42;};
我们可以编写一个与isShorter函数完全相同功能的lambda:
[] (const string &a,const string &b)
{return a.size()<b.size();}
空捕获列表表明此lambda不使用它所在函数中的任何局部变量。
那么对于调用该lambda表达书的函数为
sort(words.begin(),words.end(),
[](const string &a,const string &b)
{return a.size()<b.size();}
一个lambda表达式只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数体中使用该变量。
参考:《C++primer》(第五版)