c++中的可调用对象有以下几种:
- 函数
- 函数指针
bind
创建的对象lambda
表达式- 重载函数调用运算符的类
- 函数对象
都可以在使用算法时作为谓词来调用
lambda表达式
[capture list] (parameter list) -> return type { function body }
capture
是一个lambda表达式所在函数中定义的局部变量列表,可以捕获使用,可以通过加上 &
进行引用捕获,不加&
表示值捕获
可以忽略返回类型和参数列表,但必须要有捕获列表和函数体
auto f = [] { return 42; }
cout << f() << endl; // 打印 42
如果 lambda 表达式包含任何单一 return 语句之外的内容,且未指定返回类型,则返回
void
使用 lambda 调用 stable_sort
//按长度排序
stable_sort (words.begin(), words.end(), [] (const string &a, const string &b) { return a.size() > b.size(); } );
类重载函数调用运算符
定义一个类,重载函数调用运算符
class ShorterString {
public:
bool operator() (const string &s1, const string &s2) const
{ return s1.size() < s2.size(); }
}
可以使用 ShorterString
的未命名对象来代替 lambda
表达式
stable_sort( words.begin(), words.end(), ShorterString() );
函数对象
c++标准库定义了多个表示运算符的函数对象,常用来替换算法中的默认运算符
算术 | 关系 | 逻辑 |
---|---|---|
plus<type> | equal_to<Type> | logical_and<Type> |
minus<Type> | not_equal<Type> | logical_or<Type> |
multiplies<Type> | greater_<Type> | logical_not<Type> |
divides<Type> | greater_equal<Type> | |
modulus<Type> | less<Type> | |
negate<Type> | less_equal<Type> |
使用sort()
函数默认是按照从小到大排序,可以在sort()
加入greater<type>
按照从大到小排序,替换sort()
中的<
运算符 :
sort(svec.begin(), svec.end(), greater<string>() );
如果我们试图比较两个无关指针将产生未定义的行为,而使用标准库函数可以解决。
比如我希望通过比较指针的内存地址来sort
指针的vector
:
vector<string *> nameTable; //指针的 vector
sort(nameTable.begin(), nameTable.end(), [] (string *a, string *b) { return a < b; }); //错误: nameTable 中的指针之间没有关系
sort(nameTable.begin(), nameTable.end(), less<string*> () ); //正确