[Development] Update on Q_FOREACH (was: Re: QStringLiteral vs QLatin1String , foreach vs for range)

Marc Mutz marc.mutz at kdab.com
Wed May 11 15:30:04 CEST 2016


On Wednesday 20 January 2016 11:17:02 Knoll Lars wrote:
> On 20/01/16 11:58, "Development on behalf of Marc Mutz" <development-
bounces at qt-project.org on behalf of marc.mutz at kdab.com> wrote:
> >On Wednesday 20 January 2016 08:19:04 Thiago Macieira wrote:
> >> On Wednesday 20 January 2016 08:12:58 André Somers wrote:
> >> > Where is this qAsConst coming from? When was it introduced? Where is
> >> > it documented?
> >> 
> >> Commit 264c72837d6ff717a248dd180c2dfb45391c6aab, in dev. No api docs.
> >
> >It was intended as private API for use within Qt. If the sentiment is that
> >it should be public, I'll add proper docs.
> >
> >If the sentiment is also that we should start to discourage the use of
> >Q_FOREACH, then I'll add a \note to its docs pointing at qAsConst +
> >range-for.
> 
> +1 to both. Let's encourage people to use range-for and qAsConst instead of
> foreach.

Qt 5.7 will have a QT_NO_FOREACH macros (currently integrating) which you can 
define for your library after porting away from Q_FOREACH/foreach to prevent 
new uses from creeping in:

  DEFINES += QT_NO_FOREACH

To help modules that want to apply this macro, please don't add new uses of 
Q_FOREACH or foreach to header files (public or private) because such use 
leaks into other user's code. I'll fix the existing uses in 5.7, if you don't 
beat me. Unless you're targeting 5.6, please try not to add new uses of 
foreach anywhere, strongly preferring C++11 range-for.

I note in passing that Q_FOREACH / foreach was never intended to be used in Qt 
library code, because it generates inferior code to all other looping 
constructs: https://codereview.qt-project.org/78965

In my measurements, you can expect 80-100B in text size saved per Q_FOREACH 
loop converted to C++11 range-for. More if you happened to use Q_FOREACH on a 
QVarLengthArray ;)

Small porting guide:

  - Q_FOREACH(type item, functionCall())
  + const auto items = functionCall();
  + for (type item : items)

  - Q_FOREACH(type item, const container)
  + for (type item : const container)

  - Q_FOREACH(type item, mutable container)
  + for (type item : qAsConst(mutable container))
  + // if 'container' is not modified (directly or indirectly) in the loop
  + // body, otherwise iterate over a copy (as Q_FOREACH did)

Thanks,
Marc

-- 
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
Tel: +49-30-521325470
KDAB - Qt, C++ and OpenGL Experts



More information about the Development mailing list