c++ for_each 用法

c++ for_each 用法主要参考 for each 的用法 转载自蕭鴻森的 blog 找不到原文的链接 在接触 C 特性 Lambda 时 接触到 for each 没想到这内容还挺多的 所以 先了解 for each 再学习 Lambda 这些文章其实都是在网上参考前人的博客 有些自己整理 有些不需要修改 本意是为自己学习 以备以后查阅之用 如有侵权 联系我即可 本文代码大部分自己写过 使用 MinGW 原文非常好 建议

引入

先看一段不用for_each 的代码:

#include 
    #include 
    #include 
    using namespace std; int main() { int a[] = { 1, 2, 3, 4}; vector<int> v(a, a+sizeof(a)/sizeof(int)); for(vector<int>::iterator itor = v.begin();itor!=v.end();++itor) { cout<<*itor< 
  

其中这句代码:

 for(vector<int>::iterator itor = v.begin();itor!=v.end();++itor)

略长,如果不常写,倒是很容易手生。

template<typename InputIterator, typename Function> Function for_each(InputIterator beg, InputIterator end, Function f) { while(beg != end) f(*beg++); }

由以上source可知,for_each()只能配合global function和function object。

以下将对procedure based、object oriented、generics三种paradigm与for_each()搭配做探讨。

Procedure Based与for_each()搭配

1、不传入参数

void fun(int i ) { cout< 
  
    int main() { 
   int a[] = { 
   1, 
   2, 
   3, 
   4}; 
   vector<int> v(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(v.begin(), v.end(), fun); } 
  

2、传入参数

要传入参数给global function ,需要使用 ptr_fun() 这个 function adapter 将global function 转成function object , 然后再用bind2nd() 将参数bind成一个function object。(这句话好拗口)。

void fun(int i, const char* str) { cout< 
  
    int main() { 
   int a[] = { 
   1, 
   2, 
   3, 
   4}; 
   vector<int> v(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(v.begin(), v.end(), bind2nd(ptr_fun(fun), 
   "Element:")); } 
  

Object Oriented 与for_each 搭配

1、不传入参数,使用function object

#include 
    #include 
    #include 
    #include 
    using namespace std; struct Play { void operator () (int i) { cout< 
  
    int main() { 
   int a[] = { 
   1, 
   3, 
   4, 
   5}; 
   vector<int> vc(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(vc.begin(), vc.end(), Play()); } 
  

输出是

#include 
    #include 
    #include 
    #include 
    using namespace std; struct Play { Play() { cout<<"new a Play"< 
  
    const Play&) { 
   cout<< 
   "new a copy Play"< 
   
     void 
    operator () ( 
    int i) { 
    cout< 
    
      cout<< 
     "dispose a Play"< 
     
       int main() { 
      int a[] = { 
      1, 
      3, 
      4, 
      5}; 
      vector<int> vc(a, a+ 
      sizeof(a)/ 
      sizeof( 
      int)); for_each(vc.begin(), vc.end(), Play()); 
      cout<< 
      "See something"< 
       
      
     
    
  

此时输出是:

2、传入参数

可以通过构造函数的技巧传入参数

#include 
    #include 
    #include 
    #include 
    using namespace std; struct Play { const char* str; Play(const char* s):str(s) {} void operator () (int i) { cout< 
  
    int main() { 
   int a[] = { 
   1, 
   3, 
   4, 
   5}; 
   vector<int> vc(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(vc.begin(), vc.end(), Play( 
   "Element:")); } 
  

Member function 与 for_each 搭配

1、不传入参数

通过mem_fun_ref() 这个funtion adapater 将 member funtion 转成 function object。

#include 
    #include 
    #include 
    #include 
    using namespace std; class Door { public: void open() const { cout<<"open door horizontally"< 
  
    class DoorController { 
   protected: 
   vector 
     _doorVec; 
   public: 
   void addDoor(Door door) { _doorVec.push_back(door); } 
   void openDoor() 
   const { for_each(_doorVec.begin(), _doorVec.end(), mem_fun_ref(&Door::open)); } }; 
   int main() { DoorController dc; dc.addDoor(Door()); dc.addDoor(Door()); dc.openDoor(); } 
  

输出:

值得注意的是,mem_fun_ref() 用在 object 的 member function。若要搭配多态,vector必须放pointer,也就是得使用object pointer的member function,此时得使用mem_fun()将member function转成function object。

2、传入参数

要使用 bind2nd

#include 
    #include 
    #include 
    #include 
    using namespace std; class AbstractDoor { public: virtual void open(const char* str) const = 0; //定义纯虚函数 virtual ~AbstractDoor() {} }; class HorizontalDoor: public AbstractDoor { public: void open(const char* str) const { cout< 
  
    "open door horizontally"< 
   
     class VerticalDoor: 
    public AbstractDoor { 
    public: 
    void open( 
    const 
    char* str) 
    const { 
    cout< 
    
      "open door vertically"< 
     
       class DoorController { 
      protected: 
      vector 
        _doorVec; 
      public: 
      void addDoor(AbstractDoor* door) { _doorVec.push_back(door); } 
      void openDoor() 
      const { for_each(_doorVec.begin(), _doorVec.end(), bind2nd(mem_fun(&AbstractDoor::open), 
      "Jhon ")); } ~DoorController() { for_each(_doorVec.begin(), _doorVec.end(), [](AbstractDoor* p) { 
      delete p; p = 
      nullptr; }); } }; 
      int main() { DoorController dc; dc.addDoor( 
      new HorizontalDoor()); dc.addDoor( 
      new VerticalDoor()); dc.openDoor(); } 
      
     
    
  

引用一句很重要的用法:

mem_fun_ref的作用和用法跟mem_fun一样,唯一的不同就是:当容器中存放的是对象实体的时候用mem_fun_ref,当容器中存放的是对象的指针的时候用mem_fun。

Generics与for_each()搭配

1. Funtion template

1.1 不传入参数

#include 
    #include 
    #include 
    #include 
    using namespace std; template<typename T> void play(T elem) { cout< 
  
    int main() { 
   int a[] = { 
    
   1, 
   3, 
   4, 
   5}; 
   vector<int> vc(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(vc.begin(), vc.end(), play< 
   int>); } 
  

1.2 传入参数

#include 
    #include 
    #include 
    #include 
    using namespace std; template<typename T, char str> void play(T elem) { cout< 
  
    int main() { 
   int a[] = { 
    
   1, 
   3, 
   4, 
   5}; 
   vector<int> vc(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(vc.begin(), vc.end(), play< 
   int, 
   'a'>); } 
  

这里无法传入字串或者别的指针的类型。

2. class template

2.1不传入参数

#include 
    #include 
    #include 
    #include 
    using namespace std; template<typename T> class Play/*:public unary_function 
   
     */ 
    //我不懂为什么原文需要这个? { public: void operator() (T elem) { cout< 
  
    int main() { 
   int a[] = { 
    
   1, 
   3, 
   4, 
   5}; 
   vector<int> vc(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(vc.begin(), vc.end(), Play< 
   int>()); } 
  

2.2 传入参数

#include 
    #include 
    #include 
    #include 
    using namespace std; template<typename T, typename V> class Play/*:public unary_function 
   
     */ 
    //我不懂为什么原文需要这个? { V _str; public: Play(V str):_str(str) {} void operator() (T elem) { cout<<_str< 
  
    int main() { 
   int a[] = { 
    
   1, 
   3, 
   4, 
   5}; 
   vector<int> vc(a, a+ 
   sizeof(a)/ 
   sizeof( 
   int)); for_each(vc.begin(), vc.end(), Play< 
   int, 
   const 
   char*>( 
   "Element ")); } 
  

END

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/199421.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 下午1:01
下一篇 2026年3月20日 下午1:01


相关推荐

  • 详解git fetch与git pull的区别

    详解git fetch与git pull的区别gitfetch 和 gitpull 都可以将远端仓库更新至本地那么他们之间有什么区别呢 想要弄清楚这个问题有有几个概念不得不提 FETCH HEAD 是一个版本链接 记录在本地的一个文件中 指向着目前已经从远程仓库取下来的分支的末端版本 commit id 在每次本地工作完成后 都会做一个 gitcommit 操作来保存当前工作到本地的 repo 此时会产生一个 commit id 这是一个能

    2026年3月26日
    1
  • java项目视频

    java项目视频java版qq:http://pan.baidu.com/s/1orpxsssh智慧团:http://pan.baidu.com/s/1cLU4m巴巴运动网项目:http://pan.baidu.com/s/15SiSW国家电力项目:http://pan.baidu.com/s/1Gb7KI(强烈推荐)银行业务调度系统:http://pan.baidu.com/s/1kn4Gq

    2022年10月3日
    4
  • 开关量电压转换电路

    开关量电压转换电路单片机的I/O口承受输入电压一般是-5V到 +5V,如果一个开关接的距离比较远,就容易受到线路干扰、线缆本身的电阻率影响导致MCU无法识别。虽然MCU的I/O的输入是“高阻抗”的,但是还是很难确保远距离后的影响。  左边可以输入0~12V,右边可以很稳定的输出0~5V

    2022年5月5日
    43
  • 最全的js正则表达式用法大全_js正则表达式语法大全

    最全的js正则表达式用法大全_js正则表达式语法大全匹配中文字符的正则表达式:[u4e00-u9fa5]评注:匹配中文还真是个头疼的事,有了这个表达式就好办了匹配双字节字符(包括汉字在内):[^x00-xff]评注:可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)匹配空白行的正则表达式:ns*r评注:可以用来删除空白行匹配HTML标记的正则表达式:]*>.*?|评注:网上流

    2025年6月1日
    3
  • 成员变量和局部变量的区别是什么_实例变量和成员变量的区别

    成员变量和局部变量的区别是什么_实例变量和成员变量的区别成员变量和局部变量的区别?A:在类中的位置不同成员变量:在类中方法外局部变量:在方法定义中或者方法声明上B:在内存中的位置不同成员变量:在堆内存局部变量:在栈内存C:生命周期不同成员变量:随着对象的创建而存在,随着对象的消失而消失局部变量:随着方法的调用而存在,随着方法的调用完毕而消失D:初始化值不同成员变量:有默认初始化值局部变量:没有默认初始化值,必须定义,赋值,然后才…

    2025年7月17日
    7
  • 大数据ETL开发之图解Kettle工具(入门到精通)

    大数据ETL开发之图解Kettle工具(入门到精通)0ETL简介ETL(Extract-Transform-Load的缩写,即数据抽取、转换、装载的过程),对于企业或行业应用来说,我们经常会遇到各种数据的处理,转换,迁移,所以了解并掌握一种ETL工具的使用,必不可少。市面上常用的ETL工具有很多,比如Sqoop,DataX,Kettle,Talend等,作为一个大数据工程师,我们最好要掌握其中的两到三种,这里我们要学习的ETL工具是Kettle!1Kettle简介1.1Kettle是什么Kettle是一款国外开源的ETL工具,纯ja

    2022年6月13日
    60

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号