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
AD

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

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

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

  • Result:80points,
  • Rating points4
m

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

  • Result:20points,
  • Rating points-10
Last comments
Evgenii Legotckoi
Evgenii LegotckoiOct. 31, 2024, 2:37 p.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 8:19 a.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 7:51 a.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 11:02 a.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrFeb. 8, 2024, 6:43 p.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 24, 2024, 3:11 p.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 6:04 a.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 3:49 a.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 9:10 a.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks