Evgenii Legotckoi
Evgenii LegotckoiMay 15, 2018, 2:26 a.m.

Qt/C++ - Tutorial 079. foreach vs range-based for in C++11?

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.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

a
  • April 10, 2020, 12:41 a.m.

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/ )

Comments

Only authorized users can post comments.
Please, Log in or Sign up
г
  • ги
  • April 23, 2024, 11:51 p.m.

C++ - Test 005. Structures and Classes

  • Result:41points,
  • Rating points-8
l
  • laei
  • April 23, 2024, 5:19 p.m.

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:10points,
  • Rating points-10
l
  • laei
  • April 23, 2024, 5:17 p.m.

C++ - Тест 003. Условия и циклы

  • Result:50points,
  • Rating points-4
Last comments
k
kmssrFeb. 9, 2024, 3:43 a.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVADec. 25, 2023, 7:30 p.m.
Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
J
JonnyJoDec. 25, 2023, 5:38 p.m.
Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
G
GvozdikDec. 19, 2023, 6:01 a.m.
Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
Now discuss on the forum
G
GarApril 22, 2024, 1:46 p.m.
Clipboard Как скопировать окно целиком в clipb?
DA
Dr Gangil AcademicsApril 20, 2024, 3:45 p.m.
Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
a
a_vlasovApril 14, 2024, 2:41 p.m.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
Павел Дорофеев
Павел ДорофеевApril 14, 2024, 10:35 a.m.
QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
f
fastrexApril 4, 2024, 12:47 p.m.
Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

Follow us in social networks