为什么Qt foreach要创建一个容器的副本?

Why does Qt foreach create a copy of the container?

本文关键字:一个 副本 foreach Qt 创建 为什么      更新时间:2023-10-16

文档只是简单地说明了这一点,但没有解释原因:

Qt在进入a时自动获取容器的副本foreach循环。如果你在迭代时修改容器,那不会影响循环。(如果不修改容器,则复制仍然发生,但由于隐式共享复制容器非常快。)因为foreach创建了一个容器的副本,所以使用变量的非const引用不允许修改原来的容器。它只影响拷贝,这可能不是你想要什么

对我来说,这看起来像是一个自我强加的障碍,使Qt的foreach比它本来可以更有用-现在你不能用它来修改元素。

我听说boost的foreach和新的c++ 11 for (auto iter : array)不执行复制(尽管我不熟悉它们中的任何一个)。

那么复制背后的基本原理是什么呢?

Qt开发人员已经决定用例,当您在循环中修改容器(如在信号处理程序中,也就是插槽等)而不修改原始容器时,它应该防止意外。

用信号槽机制来追踪某些东西是否被修改可能会很棘手。如果使用该容器成员发出信号,则基本上取决于插槽。当然,您总是需要执行外部复制,否则

另一个优点是,您可以将方法调用传递给第二个参数,而无需连续重新求值,因为副本将在第一次创建。如果您问我,这实际上是一个相当简洁的功能,因为您经常希望迭代关联数组键或值,如myHash.keys()myHash.values()

你可以说boost也有信号槽机制。是的,在我看来,这只是一种不同的方式。他们不必总是做同样的事情。: -)

不同的人对API、样式等有不同的品味。毕竟,您手中有所有的工具来实现您计划处理的任何用例。

你也可以争辩说它可能不是你想要的,你可以做一个显式的复制。这很公平,您可以使用Boost或c++中的标准foreach来做到这一点。

这里的复制没有性能问题,因为对于没有修改的正常迭代,写时复制(也称为隐式共享)已经足够好了。它有一些性能开销,但是可以忽略不计。

对于这样的用例,正确的Qt语义应该是使用迭代器设计模式。例如,Qt的迭代器类都遵循"Java风格"。
相关文章: