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 notandSince 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.
foreachis 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
foreachas 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
itemcan be mutable. But thelisthas 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
forwrongly, 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. -
It will be removed in a future version of Qt
There has actually been a decision made to cancel this removal.
foreachis 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
foreachas 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
itemcan be mutable. But thelisthas 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
forwrongly, 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. -
@sierdzio
The following type of construct does not detach/copy, does it?const QVector<int> &intVec; for (int i : intVec)@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.
-
It will be removed in a future version of Qt
There has actually been a decision made to cancel this removal.
foreachis 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
foreachas 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
itemcan be mutable. But thelisthas 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
forwrongly, 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.@sierdzio Thanks for your reply!
But I'm still having some questions:
1.The
itemcan be mutable. But thelisthas to be const,What does this mean? How can
itembe mutable whenlistis const? Are you saying aboutmutablemember 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.
Willforeachdo a deep copy iflistis not const? If not, why not?
I've read the source code ofQ_FOREACHinqglobal.h. Expect that it copy the container first, it seems much like whatranged forreally do then (usingbegin()andend()), am I wrong? -
@sierdzio Thanks for your reply!
But I'm still having some questions:
1.The
itemcan be mutable. But thelisthas to be const,What does this mean? How can
itembe mutable whenlistis const? Are you saying aboutmutablemember 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.
Willforeachdo a deep copy iflistis not const? If not, why not?
I've read the source code ofQ_FOREACHinqglobal.h. Expect that it copy the container first, it seems much like whatranged forreally 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
itemcan be mutable. But thelisthas to be const,What does this mean? How can
itembe mutable whenlistis const? Are you saying aboutmutablemember 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.
Willforeachdo a deep copy iflistis not const? If not, why not?
I've read the source code ofQ_FOREACHinqglobal.h. It seems much like whatranged fordo really (usingbegin()andend()), am I wrong?As far as I know, it will not do a deep copy unless absolutely necessary.
-
@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
itemcan be mutable. But thelisthas to be const,What does this mean? How can
itembe mutable whenlistis const? Are you saying aboutmutablemember 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.
Willforeachdo a deep copy iflistis not const? If not, why not?
I've read the source code ofQ_FOREACHinqglobal.h. It seems much like whatranged fordo really (usingbegin()andend()), am I wrong?As far as I know, it will not do a deep copy unless absolutely necessary.