STL中的for_each()函数

for_each()函数是C++ STL中的一个遍历函数,函数原型如下:

for_each(InputIterator first, InputIterator last, Function functor);

一般情况下使用的时候都是把first作为容器遍历的起始点指针,last是容器的末尾。重点提到的是functor(仿函数)。

仿函数是一种在模板类编程时的封装手法,本质上的仿函数是一种类(class)。但是实际起到的是一种函数的作用,在这个所谓的class中通常都是一个operator()的重载,这个重载是根据programmer的需求产生的,通过调用类的构造函数就使得这个类有了函数的行为。进一步的解释就是,在写代码的时候,总有一部分代码的重用率非常高,通常的情况下我们会把这段代码写成一个顶层函数放在类外,任何的成员函数都可以去调用或访问,但是在编写代码的同时也会产生大量的全局变量,很难维护。为了提高代码的内聚度,我们选择将这部分代码封装到一个类中,通过调用类的含参或默认构造函数来执行这段代码,我们将这种做法成为仿函数。

仿函数的机制为编写代码提供了很好的有利于资源管理的手段,如果得到恰当应用的话会写出质量很高的代码。

那么我们回过头来看看for_each(),for_each()具有如下的特性:

i. for_each()对当前[begin, end)范围内的所有成员进行访问;

ii. 仿函数对每个成员进行相应操作;

iii. for_each()返回functor的一个副本;

iv. for_each()忽略functor的任何返回值;

v. 算法时间复杂度为 O(n),n为容器中的变量数目.

特性 iii 和 iv 在写的时候不太好理解,个人的思路是for_each()的返回值需要用户使用一个相同类型的变量进行记录,函数本身忽略仿函数对当前参量的任何处理,也就是说无法记录参量的最终状态。

下面贴上一段选自cplusplus.com上的样例使用代码:

// for_each example
#include <iostream>     // std::cout
#include <algorithm>    // std::for_each
#include <vector>       // std::vector

void myfunction (int i) {  // function:
  std::cout << ' ' << i;
}

struct myclass {           // function object type:
  void operator() (int i) {std::cout << ' ' << i;}
} myobject;

int main () {
  std::vector<int> myvector;
  myvector.push_back(10);
  myvector.push_back(20);
  myvector.push_back(30);

  std::cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), myfunction);
  std::cout << '\n';

  // or:
  std::cout << "myvector contains:";
  for_each (myvector.begin(), myvector.end(), myobject);
  std::cout << '\n';

  return 0;
}
cplusplus解释原文:点击打开链接

Data Structure and Algorithm栏目中会不定期更新一些STL的应用,以及数据结构的相关内容,包括课设以及基础知识等等。

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
不知道网上有没有Effective STL(文),我找不到,我自己整理出了这个《Effective STL(文)》共享给需要的人。<br><br>《Effective STL》目录:<br><br>前言<br>致谢<br>导读<br>容器<br>条款1:仔细选择你的容器<br>条款2:小心对“容器无关代码”的幻想<br>条款3:使容器里对象的拷贝操作轻量而正确<br>条款4:用empty来代替检查size()是否为0<br>条款5:尽量使用区间成员函数代替它们的单元素兄弟<br>条款6:警惕C++最令人恼怒的解析<br>条款7:当使用new得指针的容器时,记得在销毁容器前delete那些指针<br>条款8:永不建立auto_ptr的容器<br>条款9:在删除选项仔细选择<br>条款10:注意分配器的协定和约束<br>条款11:理解自定义分配器的正确用法<br>条款12:对STL容器线程安全性的期待现实一些<br>vector和string<br>条款13:尽量使用vector和string来代替动态分配的数组<br>条款14:使用reserve来避免不必要的重新分配<br>条款15:小心string实现的多样性<br>条款16:如何将vector和string的数据传给传统的API<br>条款17:使用“交换技巧”来修整过剩容量<br>条款18:避免使用vector<bool><br>关联容器<br>条款19:了解相等和等价的区别<br>条款20:为指针的关联容器指定比较类型<br>条款21:永远让比较函数对相等的值返回false<br>条款22:避免原地修改set和multiset的键<br>条款23:考虑使用有序vector代替关联容器<br>条款24:当关乎效率时应该在map::operator[]和map-insert之间仔细选择<br>条款25:熟悉非标准散列容器<br>迭代器<br>条款26:尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator<br>条款27:用distance和advance把const_iterator转化成iterator<br>条款28:了解如何通过reverse_iterator的base得到iterator<br>条款29:需要一个一个字符输入时考虑使用istreambuf_iterator<br>算法<br>条款30:确保目标区间足够大<br>条款31:了解你的排序选择<br>条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase<br>条款33:提防在指针的容器上使用类似remove的算法<br>条款34:注意哪个算法需要有序区间<br>条款35:通过mismatch或lexicographical比较实现简单的忽略大小写字符串比较<br>条款36:了解copy_if的正确实现<br>条款37:用accumulate或for_each来统计区间<br>仿函数、仿函数类、函数等<br>条款38:把仿函数类设计为用于值传递<br>条款39:用纯函数做判断式<br>条款40:使仿函数类可适配<br>条款41:了解使用ptr_fun、mem_fun和mem_fun_ref的原因<br>条款42:确定less<T>表示operator<.<br>使用STL编程<br>条款43:尽量用算法调用代替手写循环<br>条款44:尽量用成员函数代替同名的算法<br>条款45:注意count、find、binary_search、lower_bound、upper_bound和equal_range的区别<br>条款46:考虑使用函数对象代替函数作算法的参数<br>条款47:避免产生只写代码<br>条款48:总是#include适当的头文件<br>条款49:学习破解有关STL的编译器诊断信息<br>条款50:让你自己熟悉有关STL的网站<br>参考书目<br>附录A:区域设置和忽略大小写的字符串比较<br>附录B:在微软STL平台上的注意事项<br>词汇表<br>索引<br>关于本电子书

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值