Conflict in Qt Doc on the usage of foreach keyword and range-based for?
-
Hi there!
I'm a newbie to Qt containers.https://doc.qt.io/qt-5/containers.html#the-foreach-keyword
This page saysIf in doubt, prefer foreach for Qt containers, and range based for for STL ones.
https://doc.qt.io/qt-5/qtglobal.html#foreach
But this saysNote: Since Qt 5.7, the use of this macro is discouraged. It will be removed in a future version of Qt. Please use C++11 range-for, possibly with qAsConst(), as needed.
This seems to be a conflict?If it's not, could you explain the typical usage of both?
I've learned thatrange-based for might force a Qt container to detach, whereas foreach would not
andSince foreach creates a copy of the container, using a non-const reference for the variable does not allow you to modify the original container. It only affects the copy, which is probably not what you want.
But I'm still having this doubt.Thanks!
-
It will be removed in a future version of Qt
There has actually been a decision made to cancel this removal.
foreach
is still available in Qt 6.This seems to be a conflict?
On first sight yes, but in reality - no. C++ ranged for is recommended for Qt and STL containers, but if you are unsure how to use it properly - use
foreach
as it's safer and allows you to iterate even while the container is chaning.If it's not, could you explain the typical usage of both?
foreach
- I don't use it anymore. But in general, you can use it safely with all Qt containers. It will be efficient and safe. If you use it on STL containers, you will experience a performance hit (poor performance).ranged for
- I use it for both STL and Qt containers. The only thing to remember is that Qt containers have to be const, like this:for (const auto &item : qAsConst(list)) { }
The
item
can be mutable. But thelist
has to be const, otherwise the container will detach and do a deep copy.Other than that, ranged for is good for all container types, it's fast and compilers can optimize it well.
I need to add one final hint, though: for small containers, it all does not matter much. Modern computers are so fast, that if you use
for
wrongly, the performance penalty will be in nanoseconds or miliseconds tops. Only for big containers (hundreds, thousands of items etc.) it becomes important to use the loop correctly. -
@JonB said in Conflict in Qt Doc on the usage of foreach keyword and range-based for?:
@sierdzio
The following type of construct does not detach/copy, does it?const QVector<int> &intVec; for (int i : intVec)
This is safe, yes.
-
@sierdzio Thanks for your reply!
But I'm still having some questions:
1.The
item
can be mutable. But thelist
has to be const,What does this mean? How can
item
be mutable whenlist
is const? Are you saying aboutmutable
member ofitem
?2.
otherwise the container will detach and do a deep copy.
When will the container detach? Will it immediately detach when I use a non-const reference on its item?
3.
Willforeach
do a deep copy iflist
is not const? If not, why not?
I've read the source code ofQ_FOREACH
inqglobal.h
. Expect that it copy the container first, it seems much like whatranged for
really do then (usingbegin()
andend()
), am I wrong? -
@Xeonacid said in Conflict in Qt Doc on the usage of foreach keyword and range-based for?:
@sierdzio Thanks for your reply!
But I'm still having some questions:
1.The
item
can be mutable. But thelist
has to be const,What does this mean? How can
item
be mutable whenlist
is const? Are you saying aboutmutable
member ofitem
?Item can be a non-const copy.
const QVector<int> &intVec; for (int item : intVect) { // Item can change here! But it is a COPY, it won't affect the container item += 42; }
2.
otherwise the container will detach and do a deep copy.
When will the container detach? Will it immediately detach when I use a non-const reference on its item?
I think the detach happens when you enter the loop, even if you use a const reference to the item. That's why it's super important to keep the container const. More info with all the gory details: https://www.kdab.com/goodbye-q_foreach/
3.
Willforeach
do a deep copy iflist
is not const? If not, why not?
I've read the source code ofQ_FOREACH
inqglobal.h
. It seems much like whatranged for
do really (usingbegin()
andend()
), am I wrong?As far as I know, it will not do a deep copy unless absolutely necessary.