Range-based loop in C++11

Since C++11 we have a new awesome range-based loop. It is an evolution of the always know for-loop but with implicit iterators management. In C++ we can write loops in a different way, for instance the do-while loop, the while loop and the for-loop. In this last case we take an initialization expression, a condition that must be fulfilled and finally a post-event sentence, almost always used for increment/decrement. When I started coding at the university I couldn’t use the STL containers. When I discover Qt I didn’t know anything about iterators and I kept iterating for-loops using the size/count method, that was totally aberrant as you may see. Some time ago I learned to work with iterators but with some laziness since I had to write the whole type.

For-loop before range-based loop

I know that I may by a bit basic but I like to show some old and wrong ways to write for loop. I think that sometimes in blogs we forgot that people with more basic knowledge may read this post and I like to give them the basic knowledge too. I’ve used lists because iterating them is the worst way we can do things. In a future post I’ll talk in-depth about containers and performance.

In this case it’s clear that we are looking up for a value in the list based in its position. The problem here is that a list is randomly allocated in memory so it’s really expensive to look for a value in a position. In addition we’re checking the size of a list that is not changing every iteration. We better move to iterators:

This code is almost good. The only problem is that we’re using the non-const iterator while we aren’t doing anything with the iterator neither the list. The best way would be to change for const_iterator in all sentences:

That’s righ but boring to write and tricky to remember that all iterators have to be const_iterator.

Range-based loop

Before C++11 there was no way to make the loops more readable so for that moment it was OK. Now, we have a new syntax we can use in this kind of loop called range-based loop. In addition we have auto keyword that will help us a lot. So instead of that loooooong iterator thing definition we have:

The reason we can work with that is because internally it takes the begin and end iterators and increments the iterator after the body of the loop. It allows us to work with iterators as well as const_iterators, work with object copies, const references or the reference itself. I think it’s simple and intuitive.

For-loop before range-based loop

I know that I may by a bit basic but I like to show some old and wrong ways to write for loop. I think that sometimes in blogs we forgot that people with more basic knowledge may read this post and I like to give them the basic knowledge too. I’ve used lists because iterating them is the worst way we can do things. In a future post I’ll talk in-depth about containers and performance.

In this case it’s clear that we are looking up for a value in the list based in its position. The problem here is that a list is randomly allocated in memory so it’s really expensive to look for a value in a position. In addition we’re checking the size of a list that is not changing every iteration. We better move to iterators:

This code is almost good. The only problem is that we’re using the non-const iterator while we aren’t doing anything with the iterator neither the list. The best way would be to change for const_iterator in all sentences:

That’s righ but boring to write and tricky to remember that all iterators have to be const_iterator.

Range-based loop

Before C++11 there was no way to make the loops more readable so for that moment it was OK. Now, we have a new syntax we can use in this kind of loop called range-based loop. In addition we have auto keyword that will help us a lot. So instead of that loooooong iterator thing definition we have:

The reason we can work with that is because internally it takes the begin and end iterators and increments the iterator after the body of the loop. It allows us to work with iterators as well as const_iterators, work with object copies, const references or the reference itself. I think it’s simple and intuitive.

Comments

Andre says:

Nice post, but the reference to Qt is missing.

Especially because you have to take care when using Qt containers with range-based for loops – keyword: detaching. Please see https://www.kdab.com/goodbye-q_foreach for more information.

Best regards

admin says:

Totally right!

I thought that I had added the Qt part too. As you said, the most important thing we have to care in Qt is the detaching and how it could happen when we use the range-based loops. Fortunately the use of cosnt_iterator helps in that way.

I’ll fix it ASAP with reasons when we should use qAsConst() or when it’s unnecessary =)

Leave a Reply