STL Function Object and Using Lambda
函数对象的概念
重载了运算符()。
1 | class FunctionObjectType { |
相比于普通函数有三个优点:1. 可以存储状态。2. 每个函数对象都有自己的类型,可以传递到template里定义特定行为。3. 函数对象一般比函数指针快。
例子: 用函数对象作为排序标准
1 |
|
例子: 有内部状态的函数对象
1 |
|
如果想传FunctionObject的引用,这样写:
1 | list<int> coll; |
例子: for_each()返回自己的函数对象
for_each可以返回自己的function object。就不用像上面那样写得那么费劲。
1 |
|
谓词 vs 函数对象
Perdicate(谓词)是返回布尔(或可以隐式转换成布尔)值的函数对象。
注意这个标准不足以满足STL的标准:
标准并没有规定遍历时判断谓词会执行多少次。所以谓词的正确执行决不能依赖执行次数,在设计谓词的时候就应该注意这一点。所以谓词不能有状态,应将其()重载定义为const成员函数。
预置的函数对象和Binder
需要包含头文件<functional>
。
预置的函数对象
其中bit_and, bit_or, bit_xor自从C++11才能用。
默认用less<>进行排序,所以默认顺序是升序(element < nextElement)。
unordered container默认等价标准是equal_to<>。
函数适配器和Binder
C98那些在C11后已废弃。就不总结了,只看C++11的。
bind()
1 | // bind perdicate |
mem_fn()
专用于绑定成员函数,可以不要写placeholder了。
1 | std::for_each(coll.begin(), coll.end(), std::mem_fn(&MyClass::myfunc)); |
not1()和not2()
几乎废弃了。
1 | std::sort(coll.begin(), coll.end(), std::not2(std::less<int>())); |
使用Lambda
C++11开始有。
Lambda语法
lambda不能是template。
[...] (...) mutable throwSpec -> retType {...}
- [=]表示外部作用域以值方式传入lambda。
- [&]表示外部作用域以引用方式传入lambda。
例:
1 | auto l = [] (const std::string& s) { |
例子:Lambda vs. Binder
1 |
|
例子:Lambda vs. 有状态的函数对象
1 |
|
[1] The C++ Standard Library 2nd Edition