C++手稿:STL中的函数对象与函数指针
来源:互联网 发布:淘宝开网店哪里进货 编辑:程序博客网 时间:2024/05/16 05:37
先来感受一下C++中的函数对象和函数指针:
template<typename T>void printer(int a, int b, T func){ cout<<func(a, b)<<endl;}
在STL中定义了很多像上面这样的模板,这里的T是一个可调用(实现了括号运算符)的东西。 这使得我们在使用模板时可以指定一个计算策略,它可以是函数对象,也可以是函数指针。
Less<int>
便是一个常见的函数对象,常用来配置容器或算法。<functional>
中定义了很多这样的函数对象。
函数指针
函数指针通常用来将函数传参或存储。例如:
int sum(int a, int b){ return a+b;}int main(){ printer(2, 3, sum); return 0;}
上述的printer
调用方式,编译器会生成对应的函数实例:
void printer(int a, int b, int (*func)(int, int)){ cout<<func(a, b)<<endl;}
这里T
的类型是int (*)(int, int)
。
如果你是python或者javascript程序员的话,上述过程没有什么特别的。 唯一要注意的是
func
的声明方式,星号要和标识符括起来:(*func)
。
函数对象
函数对象是重载了括号运算符的类的实例,它也可以这样调用:func(a, b)
。例如:
class Sum{public: int operator()(int a, int b){ return a+b; }};int main(){ printer(2, 3, Sum()); return 0;}
编译器会生成这样的函数实例:
void printer(int a, int b, Sum s){ cout<<s(a, b)<<endl;}
函数对象可以实现更加复杂的有状态的运算,因为对象可以有更多的属性和方法。
std::accumulate
#include <iostream> // std::cout#include <functional> // std::minus#include <numeric> // std::accumulateint myfunction (int x, int y) {return x+2*y;}struct myclass { int operator()(int x, int y) {return x+3*y;}} myobject;int main () { int init = 100; int numbers[] = {10,20,30}; std::cout << std::accumulate(numbers,numbers+3,init) << std::endl; std::cout << std::accumulate (numbers, numbers+3, init, std::minus<int>()) << std::endl; std::cout << std::accumulate (numbers, numbers+3, init, myfunction) << std::endl; std::cout << std::accumulate (numbers, numbers+3, init, myobject) << std::endl; return 0;}
在这里accumulate
的第四个参数默认值为std::plus<int>()
,是一个函数对象, std::minus<int>()
也是一个函数对象,它们都是在functional
中定义的。 myfunction
是函数指针,而myobject
是自定义的函数对象。输出如下:
16040220280
摘自cplusplus.com: http://www.cplusplus.com/reference/numeric/accumulate
比较器:std::sort
需要比较元素大小的STL算法、容器的模板、容器的成员函数,都可以给定一个比较策略。它们的默认值通常是Less<T>()
。
例如,指定greater
函数对象作为比较器,就可以实现反向排序:
sort(v.begin(), v.end(), greater<int>());
std::sort
要求随机存取迭代器,list
不可用std::sort
,可以使用list::sort(Pred pr)
。
std::sort
实际上是快排,复杂度为stale_sort
则是稳定的归并排序。
比较器:模板参数
关联容器通常使用搜索树来实现,所以插入元素时需要进行比较操作。 我们在使用容器模板时可以指定比较器:
class A{ int n;public: A(int _n):n(_n){} bool operator<(const A& lhs, const A& rhs){ return lhs.n < rhs.n; }};multiset<A, less<A>> s;s.insert(A());
默认情况下关联容器使用less
模板来进行元素比较,而less
中调用了<
, 所以默认情况下插入关联容器的元素需要实现<
运算符:
如果未实现相应的比较运算符,
insert
操作会编译错。因为运算符调用本质上是函数调用。
除非注明,本博客文章均为原创,转载请以链接形式标明本文地址: http://harttle.com/2015/07/03/stl-function-objects-and-pointers.html
- C++手稿:STL中的函数对象与函数指针
- C++手稿:函数与参数
- STL函数对象:与函数指针的比较
- STL中的函数对象
- STL中的函数对象
- STL中的函数对象
- 函数指针与C的面向对象
- C语言中的函数指针与指针函数
- C语言中的函数指针与指针函数
- C语言中的函数指针与指针函数
- C语言中的函数指针与指针函数
- C语言中的函数指针与指针函数(续)
- 函数对象与函数指针
- 函数对象与函数指针
- 函数对象与函数指针
- C++手稿:虚函数与多态
- c中的函数指针
- C中的函数指针
- HTML5+ 打开关闭侧滑窗口
- C++手稿:STL入门
- scanf和循环
- 浅谈ANR及如何分析解决ANR.1
- jboss eap 6.3 域(Domain)模式配置
- C++手稿:STL中的函数对象与函数指针
- 去掉UIScrollView的滚动条
- Android 如何判断电池电量是否充足
- owncloud源码分析7--客户端上传2
- C++手稿:指针与引用
- Qt网络获取外网的网络信息
- XML 包含函数fn:contains(string1,string2)的用法
- 最低公共祖先Lowest Common Ancestor of a Binary Tree
- Linux下开机启动sh文件