Почему foreach выполняет итерацию с помощью ссылки const?

Я пытаюсь сделать следующее:

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

Похоже, что это должно быть законным, но я получаю ошибку, жалуясь, что она cannot convert from 'const QString' to 'QString &'.

Почему Qt foreach выполняет итерацию с помощью ссылки const?

Ответ 1

Как объяснено в Документация Qt Generic Containers:

Qt автоматически берет копию контейнера, когда он входит в цикл foreach. Если вы изменяете контейнер, когда выполняете итерацию, это не повлияет на цикл. (Если вы не изменяете контейнер, копия все же имеет место, но благодаря неявному совместному копированию контейнер выполняется очень быстро.) Аналогично, объявляя переменную как неконстантную ссылку, чтобы изменить текущий элемент в список не будет работать.

Он создает копию, потому что вам может потребоваться удалить элемент из списка или добавить элементы во время цикла, например. Недостатком является то, что ваш прецедент не будет работать. Вместо этого вам придется перебирать список:

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

Немного больше набрав, но не слишком много.

Ответ 2

или вы можете использовать

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

Ответ 3

Я полагаю, что Qt foreach берет временную копию исходной коллекции перед ее итерацией, поэтому не имеет смысла иметь неконстантную ссылку в качестве модификации временной копии, которая не будет иметь никакого эффекта.

Ответ 4

Возможно, для вашего случая:

namespace bl = boost::lambda;
std::for_each(a.begin(),a.end(),bl::_1 += "s");

Ответ 5

С С++ 11 Qt теперь поощряет этот стандартный синтаксис for вместо Qt foreach:

QList<QString> a;
for(auto& s : a)
{
    s += "s";
}