【发布时间】:2026-02-10 08:30:01
【问题描述】:
我尝试执行以下操作:
QList<QString> a;
foreach(QString& s, a)
{
s += "s";
}
这看起来应该是合法的,但我最终得到一个错误,抱怨它cannot convert from 'const QString' to 'QString &'。
为什么 Qt foreach 使用 const 引用进行迭代?
【问题讨论】:
我尝试执行以下操作:
QList<QString> a;
foreach(QString& s, a)
{
s += "s";
}
这看起来应该是合法的,但我最终得到一个错误,抱怨它cannot convert from 'const QString' to 'QString &'。
为什么 Qt foreach 使用 const 引用进行迭代?
【问题讨论】:
如Qt Generic Containers Documentation 中所述:
Qt 在进入 foreach 循环时自动获取容器的副本。如果您在迭代时修改容器,则不会影响循环。 (如果不修改容器,复制仍然会发生,但由于隐式共享,复制容器非常快。)同样,将变量声明为非常量引用,以便修改当前项该列表也不起作用。
它会创建一个副本,因为您可能希望在循环时从列表中删除一个项目或添加项目。缺点是您的用例将不起作用。您将不得不迭代列表:
for (QList<QString>::iterator i = a.begin(); i != a.end(); ++i) {
(*i) += "s";
}
打字多一点,但不要太多。
【讨论】:
或者你可以使用
QList<QString> a;
BOOST_FOREACH(QString& s, a)
{
s += "s";
}
【讨论】:
在 C++11 中,Qt 现在鼓励使用这种标准的 for 语法,而不是 Qt foreach:
QList<QString> a;
for(auto& s : a)
{
s += "s";
}
【讨论】:
我相信 Qt 的 foreach 在迭代之前会获取原始集合的临时副本,因此使用非常量引用没有任何意义,因为修改临时副本不会产生任何效果。
【讨论】:
也许适合你的情况:
namespace bl = boost::lambda;
std::for_each(a.begin(),a.end(),bl::_1 += "s");
【讨论】: