سؤال

The documentation simply states that it does, but doesn't explain why:

Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop. (If you do not modify the container, the copy still takes place, but thanks to implicit sharing copying a container is very fast.) Since foreach creates a copy of the container, using a non-const reference for the variable does not allow you to modify the original container. It only affects the copy, which is probably not what you want.

To me it looks like a self-imposed handicap, making Qt's foreach less useful than it could have been - now you can't use it to modify elements.

I've heard that boost's foreach and the new C++11 for (auto iter : array) do not perform a copy (although I'm not familiar with any of them).

So what is the rationale behind that copying?

هل كانت مفيدة؟

المحلول

The Qt developers have decided about the use case that it should prevent from surprises when you modify the container in the loop (like in a signal handler, a. k. a. slot, etc) without modifying the original container.

It could be tricky with the signal-slot mechanism to track down whether something is modified. It would be basically up to the slot if you emit the signal with that container member. To be sure, you would always need to do the external copy otherwise.

Another advantage is that you could pass a method call to the second parameter without continuous re-evaluation because the copy will be created the first time. This is actually quite a neat feature if you ask me because often, you wish to iterate over the associate array keys or values like myHash.keys() or myHash.values().

You could argue that boost also has signal-slot mechanism. Yes, it is just a different way of doing it in my opinion. They do not have to be doing the same always. :-)

Different people have different taste about API, styling, and so on. After all, you have all the tools in your hand to achieve whatever use case you plan to deal with.

You could also argue that it may not be what you want and you would do an explicit copy instead. That is fair enough, you can go as far as that with Boost or the standard foreach in C++.

There are no performance concerns in here with the copy since for normal iteration without modification the copy-on-write (a. k. a. implicit sharing) is good enough. It has some performance overhead, but it is negligible.

The right Qt semantic for such a use case would be to use the iterator design pattern. Qt has iterator classes all over the place following the "Java style", for instance.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top