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 ;
}

微软社区的一个示例:

// 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 ( ) , sum ( )
{
} // 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 ;
}

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

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

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

关键字:for_each的更多相关文章

  1. 作为一个新手的Oracle(DBA)学习笔记【转】

    一.Oracle的使用 1).启动 *DQL:数据查询语言 *DML:数据操作语言 *DDL:数据定义语言 DCL:数据控制语言 TPL:事务处理语言 CCL:指针控制语言 1.登录 Win+R—cm ...

  2. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  3. java面向对象中的关键字

    1,super关键字 super:父类的意思 1. super.属性名 (调用父类的属性) 2. super.方法名 (调用父类的方法) 3. super([参数列表])(调用父类的构造方法) 注意: ...

  4. 关于javascript中的this关键字

    this是非常强大的一个关键字,但是如果你不了解它,可能很难正确的使用它. 下面我解释一下如果在事件处理中使用this. 首先我们讨论一下下面这个函数中的this关联到什么. function doS ...

  5. transient关键字的用法

    本篇博客转自 一直在路上 Java transient关键字使用小记 1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,Java ...

  6. Java关键字:static

    通常,当创建类时,就是在描述那个类的外观和行为.只有用new创建类的对象时,才分配数据存储空间,方法才能被调用.但往往我们会有下面两种需求: 1.我想要这样一个存储空间:不管创建多少对象,无论是不创建 ...

  7. Core Java 总结(关键字,特性问题)

    2016-10-19 说说&和&&的区别 初级问题,但是还是加入了笔记,因为得满分不容易. &和&&都可以用作逻辑与的运算(两边是boolean类型), ...

  8. Net中的常见的关键字

    Net中的关键字有很多,我们最常见的就有new.base.this.using.class.struct.abstract.interface.is.as等等.有很多的,在这里就介绍大家常见的,并且有 ...

  9. php多关键字查询

      php单一关键字查询 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 tdansitional//EN" "http: ...

随机推荐

  1. android在点击EditText的时候始终不弹出软件键盘

    场景描述:正常情况下,当点击EditText时,软键盘会弹出来.现在的要求是当点击EditText时,弹日期选择对话框,选择的结果显示在EditText上.若不处理,当点击EditText时,软键盘和 ...

  2. Shell脚本执行的四种方法

    (1).bash(或sh) [脚本的相对路径或绝对路径] [xf@xuexi ~]$ cat a.sh #!/bin/bash echo "hello world!" [xf@xu ...

  3. [转]c3p0学习-JdbcUtil工具类

    原文:https://www.cnblogs.com/jonny-xu/p/6374163.html 一.需要jar包: c3p0-0.9.1.2.jar mysql-connector-java-5 ...

  4. windows10下idea快捷键文件

    没详细测试. https://my.oschina.net/superwen/blog/833482 |快捷键|英文说明|说明|冲突 |---|---|--| |Ctrl + Shift + F||根 ...

  5. Elasticsearch删除数据操作,你必须知道的一些坑

    前两天有同事打电话问我,说ES删除数据有没有什么坑? 我当时就问,是删索引还是删索引里的数据?她回答说是删数据,我说查出这些数据直接删除就好了,没有什么坑... 后来想想,关于ES数据的删除,之前确实 ...

  6. MATLAB绘图及例子总结

    MATLAB绘图及例子总结 二维图 例 1 X1=[1,2,4,6,7,8,10,11,12,14,16,17,18,20]; Y1=[1,2,4,6,7,8,10,10,8,7,6,4,2,1]; ...

  7. 《剑指offer》树专题 (牛客10.25)

    考察的知识点主要在于树的数据结构(BST,AVL).遍历方式(前序,中序,后序,层次).遍历算法(DFS,BFS,回溯)以及遍历时借助的数据结构如队列和栈.由于树本身就是一个递归定义的结构,所以在递归 ...

  8. 搭建小规模邮件服务器(winmail-server)

    Winmail mail server邮件系统的安装及使用. 在安装之前首先要配置服务器固定的IP地址.子网掩码和DNS服务器(网关我这里暂时用不着). 先来配置IP地址信息,使两台虚拟机能够互联互通 ...

  9. SQL 查询建表SQL

    1.新建一个查询语句,按执行按钮 2.结果页面会显示一条sql语句,复制该语句即可建表 3.建表测试

  10. visualgdb 调试arm

    目录 visualgdb 调试arm 没有ssh的开发板使用telnet 使用telent的gdbserver title: visualgdb 调试arm date: 2019/11/19 10:0 ...