很多编程语言都有基于范围的 for 循环(range-based for loop)语法功能,自 C++11 起,终于将这个重要功能加入 C++ 标准中。range-based for loop 语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作。

1.基本语法

for(declaration:expression) {statement
}

其中 declaration 定义一个变量,该变量将被用于访问序列中的基础元素,每次迭代,declaration 部分的变量会被初始化为 expression 部分的下一个元素值。expression 是一个对象,用于表示一个序列。statement 是对序列中元素的操作。

2.示例

vector<int> vec{1,2,3}; // C++11 only,大括号初始化
for (int i : vec) {cout << i;
}
// 输出结果:123

上面的操作时将 vector 数组中的元素拷贝至变量 i 中,进行输出。如果想改变 vector 数组中的元素值,需要把循环变量 i 定义成引用类型,实现如下:

vector<int> vec{1,2,3}; // C++11 only,大括号初始化
for (auto& i : vec ) {i = i*i;
}
for (auto i : vec ) {cout << i;
}
// 输出结果:149

请注意,我们依然可以用 continue 语句来开始下一次迭代,使用 break 跳出循环,这一点和普通的 for 循环一样。

3.深入分析

range-based for loop语句实际上等价于如下语句:

{auto && __range = expression ; for (auto __begin = begin_expr, __end = end_expr; __begin != __end; ++__begin){ auto v = *__begin; loop_statement }
}

请注意,“等价于”并不表示编译器就是这么实现 range-based for loop,只是说两者的运行效果等价。其中 expression 是被迭代的对象, begin_expr 与 end_expr 是迭代对象的迭代器,取值有:
(1)对于数组类型 begin_expr 和 end_expr 分别等于__range__range + __bound
(2)对于 STL 中的容器,两者分别等于__range.begin()__range.end();
(3)对于其他类型,两者分别等于begin(__range)end(__range)。编译器将会通过参数类型找到合适的 begin 和 end 函数。

4.让自定义的类可以迭代

通过 range-based for loop 的等价语句可以看出,只要符合一定要求,自己定义的类也可以放在其中进行迭代。事实上要想进行迭代,一个类需要满足以下条件:
(1)拥有 begin 和 end 函数,返回值是一个可以自己定义的迭代器,分别指向第一个元素和最后一个元素。既可以是成员函数,也可以是非成员函数。
(2)迭代器本身支持 *、++、!= 运算符,既可以是成员函数,也可以是非成员函数。

示例如下:

#include <stdlib.h>
#include <iostream>
using namespace std;class IntVector {//迭代器类class Iter {public:Iter(IntVector* p_vec, int pos):_pos(pos),_p_vec(p_vec){}// these three methods form the basis of an iterator for use with range-based for loop  bool operator!= (const Iter& other) const{return _pos != other._pos;}// this method must be defined after the definition of IntVector,since it needs to use it  int& operator*() const{return _p_vec->get(_pos);}const Iter& operator++ (){++_pos;return *this;}private:        IntVector *_p_vec;int _pos;};public:IntVector(){}Iter begin(){return Iter(this,0);}Iter end(){return Iter(this, 20);}int& get(int col){return data[col];}void set(int index, int val){data[index] = val;}
private:int data[20] = {0};
};int main(){IntVector v;for (int i = 0; i < 20; i++){v.set(i, i);}for (int& i : v) { i = i*i; cout << i <<" "; }system("pause");
}

程序输出结果:

0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361

参考资料

[1] Stanley B. Lippman等著,王刚,杨巨峰译.C++ Primer 中文第5版[M]
[2] Range-based for loop (since C++11)
[3] C++11 新特性之Range-based for loops

C++11 range-based for loop相关推荐

  1. using(别名)和range based for

    using(别名)替代typedef 关键字 using 语法 别名声明是具有下列语法的声明: using 标识符 attr(可选) = 类型标识 ; (1) template < 模板形参列表 ...

  2. 使用 C++11 Range For-Loop 枚举注册表、文件夹和 WMI

    使用 C++11 range for-loop 来枚举 Windows 注册表键/值.文件夹中的文件和 Windows Management Instrumentation (WMI) 查询,可以不需 ...

  3. c++用数组初始化向量_用C ++初始化向量

    c++用数组初始化向量 In this article, we'll take a look at some of the ways to initialize a vector in C++. Th ...

  4. VS2017 C++开发环境插件推荐

    文章目录 引言 VS2017安装 Assistx安装 代码高亮 快速插入代码模板 模板介绍 新建模板 常用模板汇总 文件头说明cmh 函数注释cmf 防重复包含chg c++11 Range-Base ...

  5. Web版简易加法计算

    ##HTTP HTTP是一个客户端和服务器端请求和应答的标准(TCP).客户端是终端用户,服务器端是网站.通过使用Web浏览器.网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80 ...

  6. Bash For Loop Examples for Your Linux Shell Scripting--ref

    There are two types of bash for loops available. One using the "in" keyword with list of v ...

  7. Python|线程和进程|阻塞|非阻塞|同步|异步|生成器和协程|资源竞争|进程间通信|aiohttp库|daemon属性值详解|语言基础50课:学习(11)

    文章目录 系列目录 原项目地址 第34课:Python中的并发编程-1 线程和进程 多线程编程 使用 Thread 类创建线程对象 继承 Thread 类自定义线程 使用线程池 守护线程 资源竞争 G ...

  8. java11 是长期支持_这里有你不得不了解的Java 11版本特性说明

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  9. 表分区MySQL版本:5.5.11比5.1查询速度明显提高(4倍左右)

    实验1 1.建表: create table `t_part_test`( `id` int NOT NULL default 0, `detail` char(32) NOT NULL defaul ...

  10. python基础教程:list转换range()的打印结果

    for循环中常见的一个函数是range(),然而有时候直接打印range的时候,得到的结果却不是我们想要的,这个时候,可以用list列表来转换一下range的结果,让我们更清除的打印出range中的元 ...

最新文章

  1. Go 学习笔记(20)— Go 操作 json 文件(编码生成 json、解码 json 为 map、解码 json 为 struct)
  2. 外观模式 - 设计模式学习
  3. 你的代码将会被GitHub埋在北极,保存1000年!
  4. 作为一名Java程序员,这些Spring知识点面试官常考
  5. Python面试基础题-2018-12-26
  6. STM32的ISP升级详解
  7. Linux Hackers/Suspicious Account Detection
  8. mac下intellij idea 永久破解
  9. vue2 自定义事件 v-model .sync
  10. SQL Server 阻止组件 xp_cmdshell
  11. std::ostringstream
  12. iPhone13如何设置卡1和卡2收发信息
  13. 高德地图Amap绘制路线首尾相连问题
  14. 离散数学中求合取范式析取范式
  15. 设置div显示隐藏的N种方法
  16. 平台搭建_记一次CTFd平台搭建
  17. 多线程为什么跑的比单线程还要慢?!
  18. javascript实现完美身份证号有效性验证15位18位
  19. MySQL查询最近7天数据
  20. Connection has been closed BEFORE response异常

热门文章

  1. SWAP Detector:GrammaTech 开源 DevOps 应用安全测试工具
  2. 因不满被拒,研究员公开 IBM 企业安全软件中的4个 0day
  3. RepBaseRepeatMaskerEdition下载 | RepeatMasker
  4. mac命令行配置网络
  5. iOS 开发 申请定位
  6. 动态创建MySQL Group Replication的节点(r11笔记第84天)
  7. DOS 下编写带有日期的脚本例子
  8. Oracle virtual box 安装系统黑屏问题
  9. 关于3D Pie Chart (ActiveReport 4.2.0)的学习总结 (一)
  10. 服务器设置客户端网页安装,网页服务器和客户端