【转】foreach for each for_each引发的探讨:c++世界中的循环语句

转自:foreach for each for_each引发的探讨:c++世界中的循环语句_w_419675647的博客-CSDN博客

一 背景:

代码中看到 for each,注意,两个单词中间没有下划线,有同事问这个是不是和 for_each一样?和foreach呢?我回答应该一样,但是内心很不安,尤其是作为一个c++的多年用户。

二 资料收集整理:

1 首先来看看我们最熟悉的 for_each。

他的全名是 std::for_each,来源c++的stl。头文件<algorithm>.
当时是个模板函数了
template <class InputIterator, class Function>
Function for_each (InputIterator first, InputIterator last, Function fn);
标准库中的例子:

// for_each example
#include <iostream>     // std::cout
#include <algorithm>    // std::for_each
#include <vector>       // std::vectorvoid 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;
}  

2 再来看看foreach。

搜索引擎里可以搜到很多相关标题,但是点进去后会发现,几乎都是在讲 for_each。仅有的几篇异同点其实是个错误的宏定义。
后来试着在QT的帮助文档里找了下,果然找到了。
他是: - Global Qt Declarations
foreach(variable, container)
This macro is used to implement Qt’s foreach loop. The variable parameter is a variable name or variable definition; the container parameter is a Qt container whose value type corresponds to the type of the variable. See The foreach Keyword for details.
Note: Since Qt 5.7, the use of this macro is discouraged. It will be removed in a future version of Qt. Please use C++11 range-for, possibly with qAsConst(), as needed.
See also qAsConst().
大致的翻译:从Qt 5.7开始,不建议使用此宏。 它将在Qt的将来版本中删除。 请根据需要使用C ++ 11 range-for,可能与qAsConst()一起使用。
另请参见qAsConst()。

是的,不再建议使用。

3 最后找找for each。

真难找,好像没有这个语法,但是代码里确实有使用,代码里的关键字是两个分开的单词,也无法到到对应的定义文件。
换到bing引擎,终于还是找到了。
《https://docs.microsoft.com/en-us/cpp/dotnet/for-each-in?view=vs-2019》
原来是微软自己的定义。
Iterates through an array or collection. This non-standard keyword is available in both C++/CLI and native C++ projects. However, its use is not recommended. Consider using a standard Range-based for Statement (C++) instead.
翻译:遍历数组或集合。 此非标准关键字在C ++ / CLI和本机C ++项目中均可用。 **但是,不建议使用它。** 考虑改为使用标准的基于范围的语句(C ++)。
是的,不建议使用了。

三 聊聊c++ 世界的循环语句

1 对容器中的每一个元素都调用函数的方法有以下:

第一种:基于迭代器

for (std::vector<int>::iterator it = ve.begin(); it < ve.end(); ++it)f(*it);
for (std::vector<int>::const_iterator it = ve.cbegin(); it < ve.cend(); ++it)f(*it);
for (std::vector<int>::iterator it = ve.begin(); it != ve.end(); ++it)f(*it);
for (std::vector<int>::const_iterator it = ve.cbegin(); it != ve.cend(); ++it)f(*it);

第二种:基于下标

for (int i = 0; i != ve.size(); ++i)f(ve[i]);
for (int i = 0; i < ve.size(); ++i)f(ve[i]);
for (std::size_t i = 0; i != ve.size(); ++i)f(ve[i]);
for (std::size_t i = 0; i < ve.size(); ++i)f(ve[i]);
for (std::vector<int>::size_type i = 0; i != ve.size(); ++i)f(ve[i]);
for (std::vector<int>::size_type i = 0; i < ve.size(); ++i)f(ve[i]);

第三种:stl模板函数

std::for_each(ve.begin(), ve.end(), f);
std::for_each(ve.cbegin(), ve.cend(), f);
std::for_each(std::begin(ve), std::end(ve), f);
std::for_each(std::cbegin(ve), std::cend(ve), f); // C++14

第四种:基于范围的循环

for (auto val : ve)f(val);
for (auto &val : ve)f(val);
for (const auto &val : ve)f(val);

2 分析:

第一种方法:书写太复杂并不是所有容器的迭代器都支持小于操作容易误写成 it <= ve.end()
第二种方法:调用 ve.size()可能有效率的问题 调用 ve[i]可能有效率的问题 并不是所有的容器都支持下标操作下标的标准规范是无符号的数,所以使用int 是错误的标准并未说明下标具体用何种类型说明,所以使用std::size_t可能有可移植性的问题使用 std::vector::size_type正确,但书写太复杂了容易误写为 i <= ve.size()
第三种方法:相比前两种,不容易出错相比前两种,书写也简单多了如果在函数调用处写函数的话还是比较复杂
第四种方法:相比前三种,不容易出错相比前三种,书写更简单了直接在函数调用处写函数也很简单需要 C++11 或之后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435593.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于ArcEngine实现分组统计面积的功能

可以使用IQueryFilterDefinition里的PostfixClause来实现SQL语句里的group by, order by等的功能。 例如&#xff1a; IQueryFilter pQueryFilter new QueryFilterClass(); pQueryFilter.subfield"qsdwdm,qsxz,dlbm,sum(mj) as mj,sum(tkmj) as tkmj" pQueryFilter.w…

【转】CT中的“层“与“排“的区别

转自&#xff1a;CT中的"层"与"排"的区别 自从离开医院&#xff0c;专业培训磁共振&#xff0c;有差不多5年时间没有接触CT了。影像技术及影像医学诊断说到底是一门经验技术累积学科&#xff0c;这种学科的特点就是熟能生巧&#xff0c;几年不碰&#xff0…

交易机项目工作日志--2013-01-30

又是一个不眠之夜。 昨天王哥做的新板子&#xff0c;用我编译的内核无法启动&#xff0c;卡在串口的初始化。但用开发板光盘上自带的内核确可以启动。 对比两个内核的打印信息。 [31m[UART] DMA init CH:0 [0m[31m[UART] DMA init CH:1 [0m [31m[UART] DMA init CH:1 [0m[3…

开机显示c:\windows\windows32\config\system文件损坏或丢失的解决方法(收集)

开机显示"c:\windows\windows32\config\system文件损坏或丢失。提示用软盘或光盘启动&#xff0c;用安装盘。 XP系统system文件损坏的修复 2009-04-15 Cbsi中国PChome.net 类型: 转载 来源: 163博客 责编: 吴宏 [评论1条] 方法一&#xff1a;用原盘XP光驱启动&#xff0c;…

修改SMDK6410的调试串口为普通串口(wince系统)

环境&#xff1a; 飞凌OK6410A开发板&#xff0c; Windows CE6.0系统 最近在做GPRS通信&#xff0c;可是手头上的GPRS模块&#xff08;Q2403A&#xff09;是五线串口的&#xff08;RXD、TXD、GND、RCS、CTS&#xff09;&#xff0c;老板又不愿买新的模块。所以考虑将调试串口CO…

【转】CTA图像

转自&#xff1a;CTA图像 CT检查在临床中应用十分广泛&#xff0c;CT以其扫描速度快&#xff0c;对骨头及钙化敏感而具有部分优势。 CTA是CT血管成像&#xff0c;是CT临床应用中一个非常重要的部分&#xff0c;由于血管及其背景软组织自然对比差&#xff0c;常规CT平扫往往难以…

大白话系列之C#委托与事件讲解(一)

从序言中&#xff0c;大家应该对委托和事件的重要性有点了解了吧&#xff0c;虽然说我们现在还是能模糊&#xff0c;但是从我的大白话系列中&#xff0c;我会把这些概念说的通俗易懂的。首先&#xff0c;我们还是先说说委托吧&#xff0c;从字面上理解&#xff0c;只要是中国人…

wince的调试串口作为普通串口使用

目前wince的串口0是作为调试串口用的&#xff0c;但是因为我的案子需要3个串口&#xff0c;所以要把它改为普通串口&#xff0c;但是开机时候还是需要打印debug信息&#xff0c;鉴于此&#xff0c;我修改如下&#xff1a;debug.c中加入一行&#xff1a;int DebugConsoleEnabled…

【转】医学影像处理相关知识整理(一)

转自&#xff1a;医学影像处理相关知识整理&#xff08;一&#xff09; - 知乎 Segmentation to RT structure 近日做医疗影像处理相关的内容&#xff0c;感慨于这方面资料不全、散碎&#xff0c;遂记录自己获得的一些资料以供日后查阅。 DICOM DICOM 是医学图像和相关信息…

x210 debug口当普通串口使用

方法共三步&#xff1a; 第一步: 修改文件wince600\platform\smdkv210\common\dbgserial\dbgserial.c中的三个函数 OEMInitDebugSerial() { ... if (g_pUARTReg NULL) { #if (DEBUG_PORT DEBUG_UART0) // UART0 g_pUARTReg (UART_REG *)OALPA…

【转】卷积的本质及物理意义(全面理解卷积)

转自&#xff1a;卷积的本质及物理意义&#xff08;全面理解卷积&#xff09;_彼岸花-CSDN博客_卷积的物理意义 卷积的本质及物理意义 提示&#xff1a;对卷积的理解分为三部分讲解1&#xff09;信号的角度2&#xff09;数学家的理解&#xff08;外行&#xff09;3&#xff0…

对象结构

根对象&#xff1a;领域模型中的聚合根。代表了领域模型中一个完整的领域概念&#xff0c;如订单。子对象&#xff1a;从属于另一个对象&#xff08;父对象&#xff09;&#xff0c;是父对象的一部分。子对象的生命周期小于等于父对象的生命周期&#xff0c;如订单项。友元对象…

【转】pthread mutex 基本用法

转自&#xff1a;pthread mutex 基本用法 | feng 言 feng 语 锁是程序中经常需要用到的机制&#xff0c;尤其是多线程的程序中&#xff0c;如果没有锁的帮助&#xff0c;线程间的同 步就会非常麻烦甚至不可能。pthread中提供了mutex互斥量这种锁&#xff0c;在 linux 下经常 用…

交易机项目工作日志--2013-1-31

今天要在王哥新作的板子上实现关机功能。 当按关机键时&#xff0c;GPH0_1管脚发出中断型号&#xff0c;我检测到后给GPH0_0管脚置高电平来实现关机。 所以在系统启动和运行时&#xff0c;要保证GPH0_0管脚始终维持低电平&#xff0c;否测就关机了。 但开发板提供的bsp有一个电…

【转】软件工程能力漫谈:比质量更重要的,是项目管理能力

转自&#xff1a;软件工程能力漫谈&#xff1a;比质量更重要的&#xff0c;是项目管理能力 | ArchSummit 章淼老师在软件工程能力方面&#xff0c;积累了多年的经验&#xff0c;这个话题他之前也分享过多次&#xff0c;整体上内容有修改调整。 章老师博士毕业后在清华待了 12…

浅尝EffectiveCSharp_1

Item 1: 使用属性,避免可访问的数据成员 Use Properties Instead of Accessible Data Members 属性允许你创建一个想可访问数据的接口,而且仍然有使用方法的所有优点.Properties enable you to create an interface that acts like data access but still has all the benefit…

WINCE驱动编写

一般我们在驱动程序中需用LocalAlloc保留一块存储空间&#xff0c;然后用LocalCopy将I/O端口映射到该地址上&#xff0c;以后就可以访问该保留下来的地址了。 而对中断的处理各种设备不尽相同。如果是一个内置设备&#xff08;Built In&#xff09;&#xff0c;一般在oalintr.h…

【转】DICOM文件格式剖析(初识)

转自&#xff1a;DICOM文件格式剖析&#xff08;初识&#xff09;_MoreThinker的博客-CSDN博客_dicom格式 初识DICOM&#xff08;适合初学者&#xff09; 初识DICOM文件&#xff0c;发现网上的资料有点少&#xff0c;大部分的资料都不全&#xff0c;在这里做一下总结&#xf…

SVN各个状态:A C D M G U R I具体含义

svn status命令查看svn状态 ?&#xff1a;不在svn的控制中 A&#xff1a;add&#xff0c;新增 C&#xff1a;conflict&#xff0c;冲突; tc以他们改得为准 D&#xff1a;delete&#xff0c;删除 M&#xff1a;modify&#xff0c;本地已经修改 G&#xff1a;modify and merGed…

WINCE Driver 心得总结

一&#xff0e; Windows CE的驱动程序的区分 1&#xff0e;从加载以及接口方式来区分 可以分为本机设备驱动&#xff08;Built-In Driver&#xff09;、可加载驱动&#xff08;Loadable Driver&#xff09;以及混合型驱动。 &#xff08;1&#xff09;本机设备驱动 本机设备驱动…