Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is foreach iterating with a const reference?

Tags:

c++

foreach

qt

I try to do the following:

QList<QString> a;
foreach(QString& s, a)
{
    s += "s";
}

Which looks like it should be legitimate but I end up with an error complaining that it cannot convert from 'const QString' to 'QString &'.

Why is the Qt foreach iterating with a const reference?

like image 842
shoosh Avatar asked Oct 21 '09 13:10

shoosh


People also ask

What does const reference mean?

If you are using const reference, you pass it by reference and the original data is not copied. In both cases, the original data cannot be modified from inside the function.

Should I always use const reference?

Yes, you should use const whenever possible. It makes a contract that your code will not change something. Remember, a non-const variable can be passed in to a function that accepts a const parameter. You can always add const, but not take it away (not without a const cast which is a really bad idea).

When should you use a const reference parameter?

Pass Using Const Reference in C++ Now, we can use the const reference when we do not want any memory waste and do not change the variable's value. The above code will throw a compile error as num = num +10 is passed as a const reference.


2 Answers

With C++11, Qt now encourages this standard for syntax instead of Qt foreach :

QList<QString> a;
for(auto& s : a)
{
    s += "s";
}
like image 99
ymoreau Avatar answered Sep 22 '22 22:09

ymoreau


As explained on the Qt Generic Containers Documentation:

Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop. (If you don't modify the container, the copy still takes place, but thanks to implicit sharing copying a container is very fast.) Similarly, declaring the variable to be a non-const reference, in order to modify the current item in the list will not work either.

It makes a copy because you might want to remove an item from the list or add items while you are looping for example. The downside is that your use case will not work. You will have to iterate over the list instead:

for (QList<QString>::iterator i = a.begin(); i != a.end(); ++i) { 
  (*i) += "s";
} 

A little more typing, but not too much more.

like image 24
jamuraa Avatar answered Sep 23 '22 22:09

jamuraa