函数对象和谓词
重载函数调用操作符的类,其对象常称为函数对象,即他们是行为类似函数的对象买一个类对象,表现出一个函数的特征,就是通过“ 对象名+(参数列表)”的方式使用一个类对象,如果没上下文,完全可以把它看做一个函数对待,通过 重载类的 operator() 来实现的。
在标准库中,函数对象被广泛地使用以获得弹性,标准库中得很多算法都可以使用函数对象或者函数来作为自定的回调行为。
什么是谓词呢?
一元函数对象:函数参数 1 个;
二元函数对象:函数参数 2 个;
一元谓词:函数参数 1 个,函数返回值是 bool 类型,可以作为一个判断式;
二元谓词:函数参数 2 个,函数返回值是 bool 类型。
谓词可以是一个仿函数,也可以是一个回调函数。
代码示例:
/* 一元谓词函数举例 */ bool Compare(int i) { return ( i>=3 && i<=8); } /* 二元谓词函数举例 */ bool isShrter(const string &s1, const string &s2) { return s.size() < s2.size(); }
/* 一元函数对象举例 */ class FunShowInt { public: void operator() (int &value) { cout << value << endl; } private: int cnt; }; /* 二元函数对象举例 */ class Add { public: int operator() (int value1, int value2) { return value1 + value2; } };
预定义函数对象
预定义函数对象:标准模板库STL提前定义了很多预定义函数对象,引入头文件:#include <functional>
算数函数对象
预定义的函数对象支持加,减,乘,除,求余和取反。条用的操作符是于 type 想关联的实例
//加法 plus<types> plus<string> stringAdd; minus<types> //减法 multiplies<types> //乘法 divides<type> //除法 modilus<type> //求余 negate<type> //取反 equal_to<types> //等于 not_equal_to<types> //不等于 greater<type> //大于 greater_equal<type> //大于等于 less<type> //小于 less_equal<type> //小于等于 //逻辑函数对象 logical_and<type> //逻辑与 logical_or<type> //逻辑或 logical_not<type> //逻辑非
函数对象适配器
STL中已经定义了大量的函数对象,但是有时候需要对函数返回值做进一步的简单计算,或者填多余的参数,不能直接带入算法。函数适配器实现了这个功能,经一众函数对象转化为另一种符合要求的函数对象。
常用的适配器辅助函数:bind1st , bind2nd , not1 , not2
STL容器算法与迭代器之间的设计
- STL的容器通过类模板技术,实现数据类型和容器模型的分离。
- STL的迭代器技术实现了遍历容器的统一方法,也为STL的算法提供了统一性奠定了基础
- STL的算法,通过函数对象实现了自定义数据类型的算法运算,所以说:STL的算法也提供了统一性
- 具体例子:transform算法的诗人,通过迭代器first和ast指向的元素作为输入,通过result作为输出,通过函数对象来做自定义数据类型的运算
STL常用算法
算法部分主要由头文件<algorithm> ,<numeric> 和 <functional> 组成。
<algorithm> 是所有STL头文件中最大的一个,其中常用到的功能例如:比较,交换,查找,遍历操作,赋值,修改,反转,排序,合并等等
<numeric> 体积很小,只包括几个在序列上面进行简单数学运算的模板函数,包括加发和乘法在序列上的一些操作
<functional> 中则定义了一些模板类,用于声明函数对象
常用的查找算法:
adjacent_find();
binary_search();
count();
count_if();
equal_range();
find();
find_if();
常用的排序算法:
merge();
sort();
random_shuffle(); (shuffle是洗牌的意思)
reverse();
常用的拷贝和替换算法:
copy();
replace();
replace_if();
swap()
常用的算术和生成算法:
accumulate(); (accunulat是求和的意思)
fill():
常用的集合算法:
set_union();
set_intersection();
set_difference();
常用的遍历算法:
for_each();
transform(); (transform是变换的意思)