sas*_*alm 8 c++ foreach qt containers qtcore
文档只是说明了它,但没有解释原因:
Qt在进入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样式"之后的所有地方都有迭代器类.