【Qt】C++中的循环遍历

介绍

本文主要讨论C++中常见的几种循环遍历操作的语法:基于迭代器、基于Qt库中的foreach关键字、基于C++11新增的for循环语句。

基于迭代器的遍历

在C++容器中经常需要进行遍历操作,在C++11之前一般使用下面这种方式——基于迭代器的遍历:

    QList<QString> list {"a", "b", "c", "d"};
    QList<QString>::const_iterator citer = list.cbegin();
    for (; citer != list.cend(); ++citer)
        qDebug() << (*citer);

获取容器的开始迭代器,然后输入当前迭代器指向的值,将迭代器指向下一个位置,依次下去直到迭代器到达容器尾端迭代器终止遍历操作。这种方式提供了可变迭代器和常量迭代器,前者可以在移动遍历过程中修改容器内容,后者则是只读式的遍历。迭代器作为一种接口,可以很方便的提供给C++中其他标准库调用,如排序、插入、删除、输入输出等。

但作为一般的遍历操作,其存在一些不足,首先就是代码冗长,其次就是:我只是想遍历容器每个元素,至于容器内元素的位置我并不关心,可是上面操作你必须小心的为迭代器赋值和移动,一旦失误导致迭代器超出容器的迭代器范围会导致未知错误。

foreach关键字

在 Qt 核心库中提供了一个 foreach 关键字,其实就是一个宏,通过预处理器实现,让我们可以很方便的进行一般的遍历操作:

    QList<QString> list {"a", "b", "c", "d"};
    foreach (QString s, list)
        qDebug() << s;

这比 Qt 库中提供的类java的迭代器代码还要少一些:

    QListIterator<QString> iter(list);
    while(iter.hasNext())
        qDebug() << iter.next();

在Qt程序中使用 foreach 确实非常的方便简洁,但使用时也需要注意一点:foreach 遍历的是原始容器的副本(通过隐式共享实现,所以非常快)所以通过非const的引用修改容器对原始容器不会产生效果,不过你也无法使用非const的常量引用来修改,因为foreach内部将容器标识为了 const(有兴趣可以看下面的代码)。

#define Q_FOREACH(variable, container)                                    for (QForeachContainer<__typeof__(container)> _container_(container);     !_container_.brk && _container_.i != _container_.e;                  __extension__  ({ ++_container_.brk; ++_container_.i; }))                           for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))                                  

template <typename T>
    class QForeachContainer {
    public:
        inline QForeachContainer(const T& t) : c(t), brk(0), i(c.begin()), e(c.end()) { }
        const T c;         // 将容器标识为 const 不可修改
        int brk;
        typename T::const_iterator i, e;
    };

foreach 这种方式的优点就是:简单快捷,但不适合需要修改原始容器的场合。

C++11新曾的for循环语句

基于范围的for循环,继承了Qt库中foreach的优点,同时避免了其不足——可以修改原始容器,重写上面例子:

    for (QString s : list)
        qDebug() << s;

如果变量类型较长,可以使用auto来让编译器自动推断,如下:

    for (auto s : list)
        qDebug() << s;

通过非const变量引用修改原始容器:

for (auto &s : list)
    s = "x";

基于范围的for循环配合C++11中的auto关键字,可以大幅节省需要书写的代码量,同时也非常的简洁方便。

要说不足的话就是编译器的支持不足(C++11规范新增的),不过最新版的各种C++编译器都已经支持了,如果你的编译器支持的话,下次就记得用哦~

【Qt】C++中的循环遍历

时间: 2024-11-06 08:43:28

【Qt】C++中的循环遍历的相关文章

Android中List循环遍历性能对比

在android开发中只要是列表式风格界面我们几乎都需要用到List来存放数据,在数量很少的List的话几乎任何一种循环遍历方式整体性能都无差别,但是当我们遇到数据量稍大的时候有必要考虑用哪种方式写起来比较高性能. 常见的有以下三种: 第一种 for (String s : tests) { // .... } 第二种 int size = tests.size(); for (int i = 0; i < size; i++) { tests.get(i); } 第三种 Iterator<S

Android中List循环遍历性能对照

在android开发中仅仅要是列表式风格界面我们差点儿都须要用到List来存放数据,在数量非常少的List的话差点儿不论什么一种循环遍历方式总体性能都无区别.可是当我们遇到数据量稍大的时候有必要考虑用哪种方式写起来比較高性能. 常见的有下面三种: 第一种 for (String s : tests) { // .... } 另外一种 int size = tests.size(); for (int i = 0; i < size; i++) { tests.get(i); } 第三种 Iter

php中的循环遍历 foreach list each

foreach语句遍历数组foreach语句用于循环遍历数组,每进行一次循环,当前数组元素的值就会被赋值给变量value(也可以是其它变量),数组指针会逐一的移动. 代码示例: foreach($array as $value){  //$array要遍历的数组,$value为指针指向数组当前的值,as起到赋值的作用 code to executed;} foreach语句也可以获得数组的键名,如下:  代码示例: foreach($array as $key => $value){ echo

sqlserver中的循环遍历(普通循环和游标循环)

sql 经常用到循环,下面介绍一下普通循环和游标循环 1.首先需要一个测试表数据Student 2.普通循环 1)循环5次来修改学生表信息 --循环遍历修改记录--declare @i int   set @i=0while @i<5begin    update Student set demo = @i+5 where [email protected]    set @[email protected] +1 end--查看结果--select * from Student 2)执行后的查

微信小程序中的循环遍历问题

比如:如果在微信小程序中要遍历输出 0-9 的数,我们会使用for循环 for(var i=0;i<10;i++){ console.log(i); } 确实结果也是这样: 但是,如果我在循环时同时调用wx的api接口10次,那么输出的结果就会不同(这是产生了闭关的效应) eg:每次调用一次wx.showToast()接口,并在成功时输出循环的值. for(var i=0;i<10;i++){ wx.showToast({ title: 'haha', success:function(){

php中foreach循环遍历二维数组

最近在用tp3.2框架,在查询的时候用到了select(),这条语句返回的是二维数组,所以在对返回的数据做处理时,遇到了些麻烦,百度了下foreach,终于用foreach解决了数据的筛选问题 (因为不知道该怎么设置where条件,设置只显示Jdate字段中今天以后的数据,所以只能在select查询后的数据中进行筛选..基础没大佬,真的挺麻烦) 进入正题 官方文档中给了foreach的两种用法 foreach 语法结构提供了遍历数组的简单方式.foreach 仅能够应用于数组和对象,如果尝试应用

3、二叉树:先序,中序,后序循环遍历详解

原创博客,转载请注明出处,谢谢~~~ 设计二叉树的循环遍历算法对于深刻理解二叉树很有帮助.下面就详细分析3个循环遍历算法. 1.先序循环遍历算法. 在自己设计循环遍历算法的时候,感觉先序遍历算法设计最为容易.下面把设计思路写下来,以防遗忘. 先序循环遍历二叉树的思路最为直接,规则就是: ①. 从根结点开始沿着左孩子一直走到头,在此过程中,每到达一个结点便访问其元素值(如,输出),同时检测该结点是否有右孩子,如果有则将指向右孩子的引用入栈: ②. 第一步完成以后,弹出一个栈顶引用作为本次循环的根节

jquery中object对象循环遍历的方法

一个朋友问对象如何转为数组,当我问他为啥要转得时候,他告诉我,数组可以用js循环遍历,而对象则不可以.其实呢,对象同样可以循环遍历的啊.不用转换也可以循环!说明你对js或者jquery的某些操作不是很熟练!在这里我简单介绍一下! 案例 我们看如下对象: ? 1 2 3 4 5 6 7 8 9 var data={   张三:69,   李四:72,   王五:90,   二麻子:88,   前端博客:100,   haorooms : 98,   王大壮:99 } 假如上面是后台返回的一个key

用angularjs在循环遍历中绑定ng-model(转载---CSDN博客 )

用angularjs在循环遍历中绑定ng-model CSDN博客 原文  http://blog.csdn.net/chen2991101/article/details/19764263 angularjs的双向绑定非常的好用,当修改了一个地方的值后另外一个地方也同步修改了,如果用平时的js来写的话需要写很多代码,但是用了angularjs后只需要几行代码就能轻松搞定. 想做一个类似于淘宝的改价的功能,就是当用户拍下了宝贝后卖家给你调价的那个功能,界面就像这样: 当修改了折扣或者直接填写了优