谓词函数predicates和仿函数functors
来源:互联网 发布:外星文明不存在 知乎 编辑:程序博客网 时间:2024/05/20 04:14
谓词函数是一个判断式,一个返回bool值的函数或者仿函数。
C++ standard library P264:并非所有返回布尔值的仿函数都是合法的谓词函数。使用两个相同的参数调用一个一元谓词函数,应该总是返回相同的结果(与调用次数无关)。
使用以下代码移除一组元素中的第三个元素,却发生了意想不到的事情。
#include <iostream>#include <list>#include <algorithm>using namespace std;template <class T>void print_elements(const T& container){for(typename T::const_iterator it = container.begin(); it != container.end(); ++it){cout << *(it) << " ";}cout << endl;}class Nth{private:int nth, count;public:Nth(int n): nth(n), count(0) {}int operator() (int){return nth == ++count;}};int main(){list<int> coll;for (int i = 0; i < 9; ++i)coll.push_back(i); print_elements(coll);list<int>::iterator pos;pos = remove_if(coll.begin(), coll.end(), Nth(3));coll.erase(pos, coll.end());print_elements(coll);return 0;}
运行结果为:
coll: 1 2 3 4 5 6 7 8 9
nth removed: 1 2 4 5 7 8 9
为什么会产生这样的结果呢?这是因为remove_if内部实现中,首先调用了find_if函数来查找第一个满足pred的迭代器位置。然后再处理剩余的元素,代码如下:
template<class ForwardIterator, class Predicate>ForwardIterator std::remove_if(ForwardIterator beg, ForwardIterator end, Predicate op){beg = find_if(beg, end, op);if(beg == end){return beg;}else{ForwardIterator next = beg;return remove_copy_if(++next, end, beg, op);}}
可以看到,对后续元素调用remove_copy_if,将谓词函数返回false的元素copy至beg处,而谓词函数是以传值方式传递的,所以在remove_copy_if中,第三个元素也会被remove。
所以,一个合法的谓词函数,它的行为不应该取决于被调用次数,谓词函数不应该因为被调用而改变自身状态。故一般情况下应该将operator()声明为const成员函数。
敲代码的时候犯了一个小错误,写仿函数的operator()时,由于操作符中并未使用额外的参数,所以函数定义时默认成了不传参,结果编译错误。
for(; __first != __last; ++__first) if(!bool(__pred(*__first))) { *__result = _GLIBCXX_MOVE(*__first); ++__result; }
可以看到,在remove_if算法中,使用谓词函数时传入了*(__first),所以谓词函数定义时,形参应与容器元素类型相同,更不能省略。
0 0
- 谓词函数predicates和仿函数functors
- 泛化仿函数(functors)
- 仿函数(functors)
- 七 仿函数 functors
- 关于谓词函数predicates的介绍
- 仿函数(functors)使用
- Java中函数式编程的谓词函数(Predicates)
- C++学习_仿函数(functors)
- 谓词 仿函数 函数指针
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- STL中仿函数(functors)、类成员和mem_fun的使用
- 仿函数(functors/function objects)原理及使用
- 函数对象和谓词
- 谓词函数
- 浅析STL 谓词 + 仿函数 + 函数指针(c)
- 做产品的态度
- centos 下memcached的安装到测试
- kmp算法学习
- Android项目所遇问题
- Android 自定义ratingBar(评分小星星)的使用
- 谓词函数predicates和仿函数functors
- 【Effective Objective-C 2.0读书笔记】第一章:熟悉Objective-C
- 【Spring三】使用注解配置bean
- 常用运算符
- 8.编写程序,要求如下: 定义名为VolumeArea的抽象类,在其中定义圆周率的值为3.14159,并定义两个抽象方法volume(double r)和area(double r),它们的返回
- 【Linux学习笔记】通用I/O模型概述
- ashx 使用Session 转载
- HDU 2019 Fighting for HDU(贪心水题)
- apache+php5+sqlite3移植