zoukankan      html  css  js  c++  java
  • 关键字:for_each

    std::for_each

    先贴cppreference中对for_each的概述:

    template< class InputIt, class UnaryFunction >  //此处UnaryFunction为一元函数
    UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );
    1) Applies the given function object f to the result of dereferencing every iterator in the range [first, last), in order.  //in order按顺序
    2) Applies the given function object f to the result of dereferencing every iterator in the range [first, last)(not necessarily in order). The algorithm is executed according to policy. This overload does not participate in overload resolution  //policy政策  //participate参加
                                                        //overload resolution重载决议
    unless std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> is true.//这句话暂时不需要懂,cpp17对for_each又增加了一个重载版本而已
    For both overloads, if InputIt is a mutable iterator, f may modify the elements of the range through the dereferenced iterator. If f returns a result, the result is ignored.  //如果迭代器不是const的,则允许一元函数对解引用的对象进行修改。如果一元函数返回一个值,则返回值被忽略.
     
     
    f - function object, to be applied to the result of dereferencing every iterator in the range [first, last) 

    The signature of the function should be equivalent to the following:

     void fun(const Type &a);

    The signature does not need to have const &. 
    The type Type must be such that an object of type InputIt can be dereferenced and then implicitly converted to Type.

    for_each返回值为第三个参数,即仿函数。即通过for_each可以获得操作后的对象状态。

     贴一段用for_each清零数组的小程序:

    #include <iostream>
    #include <algorithm>
    #include <vector>
    using namespace std;
    int main()
    {
            const int elementSize = 10;
         vector<int> vec(elementSize, 1);
    for_each(begin(vec), end(vec), [&] (int &i) { i = 0; } );  //引用捕获方式,将每个值置0 for(const auto &j : vec)  //范围for循环打印 cout << j << " "; cout << endl; return 0; }

    微软社区的一个示例:

    // alg_for_each.cpp
    // compile with: /EHsc
    #include <vector>
    #include <algorithm>
    #include <iostream>
    
    // The function object multiplies an element by a Factor
    template <class Type>
    class MultValue
    {
    private:
       Type Factor;   // The value to multiply by
    public:
       // Constructor initializes the value to multiply by
       MultValue ( const Type& _Val ) : Factor ( _Val ) {
       }
    
       // The function call for the element to be multiplied
       void operator ( ) ( Type& elem ) const  //重载成可调用对象,要注意当此可调用对象需要传参时,需要额外加一个形参列表,且应该放在 () 的后面。
       {
          elem *= Factor;
       }
    };
    
    // The function object to determine the average
    class Average
    {
    private:
       long num;      // The number of elements
       long sum;      // The sum of the elements
    public:
       // Constructor initializes the value to multiply by
       Average ( ) : num ( 0 ) , sum ( 0 )
       {
       }
    
       // The function call to process the next elment
       void operator ( ) ( int elem ) 
       {
          num++;      // Increment the element count
          sum += elem;   // Add the value to the partial sum
       }
    
       // return Average
       operator double ( )  //转换操作符重载
       {
          return  static_cast <double> (sum) /
          static_cast <double> (num);
       }
    };
    
    //以下我基于范围for循环重写了一部分
    int main( ) {

      using namespace std;
      vector<int> vec;
      vector<int>::iterator iter;

    
    

      int i;
      for( i = -4; i <= 2; ++i)  //给数组赋一个初始序列
      {
        vec.push_back(i);
      }

    
    

      cout << "The original sequence is (";  //打印初始序列
      for(const auto &num : vec)
      {
        cout << num << " ";
      }
      cout << ")." << endl;

    
    

      for_each(vec.begin(), vec.end(), MultValue<int>(-2));  //将序列中的值依次乘以-2

    
    

      cout << "The mod1 sequence is (";  //打印mod1序列
      for(const auto &num : vec)
      {
        cout << num << " ";
      }
      cout << ")." << endl;

    
    

      for_each(vec.begin(), vec.end(), MultValue<int>(5));  //将序列中的值依次乘以5

    
    

      cout << "The mod2 sequence is (";  //打印mod2序列

      for(const auto &num : vec)
      {
        cout << num << " ";
      }
      cout << ")." << endl;

    
    

      double ret = for_each(vec.cbegin(), vec.cend(), Average());  //求平均值。此处用重载double操作符实现,比较难以理解。可以用如下改法:

      /*  Average tmp = for_each(vec.cbegin(), vec.cend(), Average());

         cout << tmp.xxx << endl;  //将operator double () 改为 double xxx() { return static_cast<double>(sum) / static_cast<double>(num); }

      */

      cout << "The average of mod2 is :"  //打印平均值
          << ret << endl;

     return 0;
    }

    The original sequence is (-4, -3, -2, -1, 0, 1, 2).

    The mod1 sequence is (8, 6, 4, 2, 0, -2, -4).

    The mod2 sequence is (40, 30, 20, 10, 0, -10, -20).

    The average of mod2 is :10

    此处补一下转换操作符重载的知识

    class <类型1>
    {
    public:
    operator <类型2> () { } };

    由此可见:转换操作符重载就是将类型1转换为类型2

    #include <iostream>
    using namespace std;
    
    class Ratation
    {
    private:
            long num_;
            long sum_;
    public:
            Ratation() : num_(2), sum_(1) {
            }
    
            operator double ()
            {
                    return static_cast <double> (sum_) /
                            static_cast <double> (num_);
            }
    };
    
    int main()
    {
            Ratation obj;
            double a = 1.2;
            a += Ratation();  //执行Ratation到double的转换
            cout << a << endl;  //此处输出1.7,可见Ratation被转换为双精度了。
    
            return 0;
    }

    参考:http://en.cppreference.com/w/cpp/algorithm/for_each

       https://msdn.microsoft.com/zh-cn/library/e5sk9w9k.aspx

                                                                  写于 : 2017-03-04 23:08:37

  • 相关阅读:
    魅族手机不能通过设置Style和Background展示透明Activity的解决方法
    [翻译]The dark side of AsyncTask
    Eclipse卡死在Building workspace和android library update解决方法
    影响Java代码性能的一些细节
    WebView通过loadDataWithBaseURL加载本地页面卡死
    [04] Android逐帧动画(一)
    [03] Android系统亮度调节
    iOS UIViewContentMode详解
    setObject:forKey:与setValue:forKey:的区别
    选择排序
  • 原文地址:https://www.cnblogs.com/-ttsj/p/6502528.html
Copyright © 2011-2022 走看看