STL函数对象和Lambda表达式
STL函数对象和Lambda表达式
1.基本概念
Function object是定义了operator()的object。
FunctionObjectType fo;
fo(…);调用函数对象的operator()代替函数fo()的调用。
等价于:fo.operator()(…);
函数对象的三个好处:
(1) 函数对象可以有自己的状态,因此可能是更聪明的。你可以拥有同一个函数对象的两个实例,它们可能有不同的状态。
(2) 每个函数对象是一个类型。你可以把函数对象作为模版的参数用于指定一个特定的行为。
(3)函数对象通常比函数指针更快。因为在编译时有更多的信息被定义。
2.函数对象有自己的状态,更smart
如执行加某个值:
(1) 普通函数,在编译时加10
void add10(int &elem)
{
elem += 10;
}void f1()
{
vector<int> ivec;
…
for_each(ivec.begin(), ivec.end(), add10);
}
(2) 若想在编译时加别的值,需要重写普通函数,可以使用函数模版
template <int Val> //非类型模版形参:编译时常量
void add(int &elem)
{
elem += Val;
}
void f1()
{
vector<int> ivec;
…
for_each(ivec.begin(), ivec.end(),
add<10>);
}
(3) 要想运行时加值可以用function object
既可以加上常量如10,也可以加上一个变量(运行时才知道值)。
3.作为一个type,可以作为模版的参数,如作为sorting的排序准则
4.预定义的函数对象
头文件#include<functional>定义了一些函数对象:+ – * / == != < > <= >= ! && || & | ^。
注意:less<>是排序函数排序,关联容器排序的默认准则。
equal_to<>是unordered 容器的默认相等准则。
5.Function Adapters
函数适配器是一个能够组合函数对象的函数对象。
since C++11有:
bind(op, args…); //Binds args to op
mem_fn(op); //Call op() 作为一个对象或者对象指针的成员函数。也可以&Class::memfun
not1(op); //!op(param)
not2(op); //!op(param1, param2)
最重要的是bind(), 其他用处不大
通常bind()可以绑定对像,使用std:placeholders(站位符):_1, _2传递实参。
6.Lambda 表达式
函数对象更适合于在库中的使用,lambda更适合于应用程序,更加直观。