C++11新特性——range for
很多编程语言都有range for语法功能,自C++11起,终于将这个重要功能加入C++标准中。range for语句,可以方便的遍历给定序列中的每个元素并对其执行某种操作。
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;
上面的操作时将vector数组中的元素拷贝至变量i中,进行输出。如果想改变vector数组中的元素值,需要把循环变量i定义成引用类型,实现如下:
vector<int> vec{1,2,3}; //C++11 only,大括号初始化
for (auto& i : vec ){
i=i*i;
cout << i;
}
//输出结果:149
请注意,我们依然可以用continue语句来开始下一次迭代,使用break跳出循环,这一点和普通的for循环一样。
3.深入分析
range for语句实际上等价于如下语句:
{
auto && __range = expression ;
for (auto __begin = begin_expr, __end = end_expr;__begin != __end; ++__begin) {
declaration = *__begin;
loop_statement
}
}
请注意,“等价于”并不表示编译器就是这么实现range for,只是说两者的运行效果等价。其中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 for的等价语句可以看出,只要符合一定要求,自己定义的类也可以放在其中进行迭代。事实上要想进行迭代,一个类需要满足以下条件:
(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 for
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]C++ Primer中文版(第5版)
[2]Range-based for loop (since C++11)
[3]C++11 新特性之Range-based for loops
C++11新特性——range for的更多相关文章
- 在C++98基础上学习C++11新特性
自己一直用的是C++98规范来编程,对于C++11只闻其名却没用过其特性.近期因为工作的需要,需要掌握C++11的一些特性,所以查阅了一些C++11资料.因为自己有C++98的基础,所以从C++98过 ...
- C++ 11学习和掌握 ——《深入理解C++ 11:C++11新特性解析和应用》读书笔记(一)
因为偶然的机会,在图书馆看到<深入理解C++ 11:C++11新特性解析和应用>这本书,大致扫下,受益匪浅,就果断借出来,对于其中的部分内容进行详读并亲自编程测试相关代码,也就有了整理写出 ...
- C++11新特性总结 (二)
1. 范围for语句 C++11 引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素 vector<int> vec = {1,2,3,4,5,6}; ...
- C++11新特性总结 (一)
1. 概述 最近在看C++ Primer5 刚好看到一半,总结一下C++11里面确实加了很多新东西,如果没有任何了解,别说自己写了,看别人写的代码估计都会有些吃力.C++ Primer5是学习C++1 ...
- C++ 11 新特性
C++11新特性: 1.auto 2.nullptr 3.for 4.lambda表达式 5.override ...
- [转载] C++11新特性
C++11标准发布已有一段时间了, 维基百科上有对C++11新标准的变化和C++11新特性介绍的文章. 我是一名C++程序员,非常想了解一下C++11. 英文版的维基百科看起来非常费劲,而中文版维基百 ...
- C++11新特性——大括号初始化
C++11之前,C++主要有以下几种初始化方式: //小括号初始化 string str("hello"); //等号初始化 string str="hello" ...
- C++11新特性之六——元编程
C++11新特性之六——元编程
- C++11新特性之一——Lambda表达式
C++11新特性总结可以参考:http://www.cnblogs.com/pzhfei/archive/2013/03/02/CPP_new_feature.html#section_6.8 C++ ...
随机推荐
- cp 命令有坑
cp 是个很常用的命令, 基本语法为 cp -v a b 把文件a 复制为文件b(-v为显示做了什么,这是非常安全的做法,建议新手添加此参数) 参数说明: -a:此选项通常在复制目录时使用, ...
- LOJ #6074. 「2017 山东一轮集训 Day6」子序列
#6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...
- 欧拉函数(小于或等于n的数中与n互质的数的数目)&& 欧拉函数线性筛法
[欧拉函数] 在数论,对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目.此函数以其首名研究者欧拉命名,它又称为Euler’s totient function.φ函数.欧拉商数等. 例如φ( ...
- 发布了一个基于jieba分词的ElasticSearch插件
github地址: https://github.com/hongfuli/elasticsearch-analysis-jieba 基于 jieba 的 elasticsearch 中文分词插件. ...
- 五年.net程序员Java学习之路
大学毕业后笔者进入一家外企,做企业CRM系统开发,那时候开发效率最高的高级程序语言,毫无疑问是C#.恰逢公司也在扩张,招聘了不少.net程序员,笔者作为应届生,也乐呵呵的加入到.net程序员行列中. ...
- element-ui + vue + node.js 与 服务器 Python 应用的跨域问题
跨越问题解决的两种办法: 1. 在 config => index.js 中配置 proxyTable 代理: proxyTable: { '/charts': { target: 'http: ...
- Kafka(分布式发布-订阅消息系统)工作流程说明
Kafka系统架构Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kafka是一种快速.可扩展的.设计内在就是分布式的,分区的和 ...
- JackSon学习笔记(一)
概述 Jackson框架是基于Java平台的一套数据处理工具,被称为“最好的Java Json解析器”. Jackson框架包含了3个核心库:streaming,databind,annotation ...
- M2postmortem
设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 答:我们的软件主要解决信息提取的问题.定义清晰:要提取的内容包括于计算机科学相关内容的标题.作者. ...
- 软件工程(四)数据流图DFD
结构化分析中,常用到数据模型为实体关系图,功能模型是数据流图 DFD 可以认为,一个基于计算机的信息处理系统由数据流和一系列的转换构成,这些转换将输入数据流变换为输出数据流.数据流图就是用来刻画数据流 ...