【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++中的循环遍历,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。