Qt has its own keyword foreach to iterate through the elements of the containers. This keyword was introduced before the C++11 standard and is a macro. At this point in the C++11 standard, there are range-based for loops that perform the same functionality as foreach .
But in both cases there are nuances. Let's figure it out.
To which objects can be applied
foreach and range-based for work with containers that have an iterator. In this case there are no differences. They can only be applied to objects with an iterator.
Using, program code
Let's look at the program code. Suppose we have a container
QList<QString> strings;
And we want to do something with the elements of this container, then the record for foreach will look like this
foreach (QString& str, strings) { // ToDo something }
and for range-based for the record will be the next
for (QString& str : strings) { // ToDo something }
Preprocessor
The keyword foreach is a macro, which in the end will be equivalent to this record
for (QList<QString>::iterator it = strings.begin(); it != strings.end(); ++it) { QString &str = *it; // ваш код }
But since this is a macro, we get an overhead by compilation time for processing the files by the preprocessor, which will deploy all these macros to the working code.
Speed of work
foreach runs slower range-based for loops because it performs a pre-copy of the container, as described in the Qt documentation. From the copying follows the following nuance, that if during the foreach operation you do something with the container, then this will not have an effect on the elements in the loop. In this case, implicit copying is carried out also when you do not modify the elements of the container.
This code behavior can be quite costly for STL containers, which are expensive to copy. Therefore, for this reason, it's better to use range-based for loops from the C++11 standard.
Disadvantages of range-based for
If you read the Qt documentation, you can find that they recommend still using foreach for Qt containers, and for all others (STL, Boost, etc.) use range-based for loops. This is motivated by the fact that a container with shared data during the operation of a range-based for loop can be detached from these shared data and not returned to its original state after the actions are performed, as a result of which data corruption can occur.
One such implicitly shared class is QPen, which uses deep copying when detach.
void QPen::setStyle(Qt::PenStyle style) { detach(); // detach from common data d->style = style; // set the style member } void QPen::detach() { if (d->ref != 1) { ... // perform a deep copy } }
Conclusion
In my practice, I did not encounter such problems when using range-based for loops for Qt containers, I think, perhaps this is due to the fact that you did not have to often use such loops for containers with QPen objects or other Qt classes requiring separation from shared data.
In fact, recently the use of STL containers seems to me more convenient than the Qt containers in connection with the use of functors (lambd) for searching (std:; find, std :: find_if algorithms, etc.) of specific objects in the container, instead of the usual cycle with a condition in it.
I also adhere to the point of view that it is better to use language constructs instead of MACROS. Just need to consider that there may be problems, due to the peculiarities of containers and other Qt classes.
And the final solution for using foreach vs range-based for is left to your opinion.
Since Qt 5.7 the foreach macro is deprecated, Qt encourages you to use the C++11 for instead.
http://doc.qt.io/qt-5/qtglobal.html#foreach
(more details about the difference here : https://www.kdab.com/goodbye-q_foreach/ )