【问题标题】:Why is foreach iterating with a const reference?为什么 foreach 使用 const 引用进行迭代?
【发布时间】:2026-02-10 08:30:01
【问题描述】:

我尝试执行以下操作:

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

这看起来应该是合法的,但我最终得到一个错误,抱怨它cannot convert from 'const QString' to 'QString &amp;'

为什么 Qt foreach 使用 const 引用进行迭代?

【问题讨论】:

    标签: c++ qt foreach


    【解决方案1】:

    Qt Generic Containers Documentation 中所述:

    Qt 在进入 foreach 循环时自动获取容器的副本。如果您在迭代时修改容器,则不会影响循环。 (如果不修改容器,复制仍然会发生,但由于隐式共享,复制容器非常快。)同样,将变量声明为非常量引用,以便修改当前项该列表也不起作用。

    它会创建一个副本,因为您可能希望在循环时从列表中删除一个项目或添加项目。缺点是您的用例将不起作用。您将不得不迭代列表:

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

    打字多一点,但不要太多。

    【讨论】:

    • 次要的挑剔:我更喜欢:for(QList::iterator i = a.begin(),end=a.end(); i != end; ...)跨度>
    【解决方案2】:

    或者你可以使用

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

    【讨论】:

    • 嗯,好的...当然,您可以使用不同的库!希望您有充分的理由同时使用 Boost 和 Qt,这超出了解决这个小问题的范围!
    【解决方案3】:

    在 C++11 中,Qt 现在鼓励使用这种标准的 for 语法,而不是 Qt foreach

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

    【讨论】:

      【解决方案4】:

      我相信 Qt 的 foreach 在迭代之前会获取原始集合的临时副本,因此使用非常量引用没有任何意义,因为修改临时副本不会产生任何效果。

      【讨论】:

        【解决方案5】:

        也许适合你的情况:

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

        【讨论】: