Evgenii Legotckoi
Evgenii LegotckoiMay 15, 2018, 12:26 p.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, 10: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
ДЛ

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

  • Result:60points,
  • Rating points-1
СЦ

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

  • Result:50points,
  • Rating points-4
AT

C++ - Test 001. The first program and data types

  • Result:73points,
  • Rating points1
Last comments
J
JonnyJoMarch 30, 2023, 11:57 a.m.
Qt/C++ - Lesson 021. The drawing mouse in Qt Евгений, здравствуйте! Только начал изучение Qt и возник вопрос по 21ому уроку. После написания кода, выдаёт следующие ошибки В чём может быть проблема?
АН
Алексей НиколаевMarch 26, 2023, 9:10 a.m.
Qt/C++ - Lesson 042. PopUp notification in the Gnome style using Qt Добрый день, взял за основу ваш PopUp notification , и немного доработал его под свои нужды. Добавил в отдельном eventloop'e всплывающую очередь уведомлений с анимацией и таймеро…
АН
Алексей НиколаевMarch 26, 2023, 9:04 a.m.
Qt/C++ - Lesson 042. PopUp notification in the Gnome style using Qt Включите прозрачность в композит менеджере fly-admin-theme : fly-admin-theme ->Эффекты и всё заработает.
NSProject
NSProjectMarch 24, 2023, 2:35 p.m.
Django - Lesson 062. How to write a block-template tabbar tag like the blocktranslate tag Да не я так к примеру просто написал.
Evgenii Legotckoi
Evgenii LegotckoiMarch 24, 2023, 10:09 a.m.
Django - Lesson 062. How to write a block-template tabbar tag like the blocktranslate tag Почитайте эту статью про "хлебные крошки"
Now discuss on the forum
BlinCT
BlinCTApril 1, 2023, 5:16 a.m.
Нужен совет по работе с ListView и несколькими моделями Спасибо, сейчас займусь этим.
NSProject
NSProjectMarch 31, 2023, 2:55 a.m.
Проверка комментария принадлежит он пользователю или нет DRF (Django Rest Framework) Здравствуйте! Сегодня я столкнулся с такой проблеммой. Существует модель комметариев. Где их соответственно достаточное количество. Все они выводятся при помощи запроса ajax (axios). Так ка…
P
PisychMarch 30, 2023, 2:50 a.m.
Как подсчитать количество по условию? Да! Вот так работает! Огромное Вам спасибо! ........
Evgenii Legotckoi
Evgenii LegotckoiMarch 29, 2023, 4:11 a.m.
Замена поля ManyToMany Картинки точно нужно хранить в медиа директории на сервере, а для обращения использовать ImageField. Который будет хранить только путь к изображению на сервере. Хранить изображения в базе данных…
ВА
Виталий АнисимовJan. 29, 2023, 3:17 p.m.
Как добавить виртуальную клавиатура с Т9 в своей проект на QML. Добрый день. Прошу помочь, пишу небольше приложение в Qt. Добвил в свой проект виртуальную клавиатуру от Qt. Но как добавить в него возможность изменения Т9 никак не могу понять.

Follow us in social networks