QStringList iterative end seems invalid after copy

Can someone explain to me why the following code produces different results depending on the copy of the QStringList:

#include <stdio.h> #include <QStringList> bool qtTest(bool b) { QStringList list; list.push_back("0"); list.push_back("1"); list.push_back("2"); QStringList::const_iterator it = list.end(); if (b) { // 'static' to prevent optimization static QStringList copy = list; } --it; // 2 --it; // 1 --it; // 0 ++it; // 1 ++it; // 2 --it; // 1 ++it; // 2 ++it; // end return it == list.end(); } int main(int, char *[]) { printf("equality with copy: %d", qtTest(true)); printf("equality without copy: %d", qtTest(false)); return 0; } 

Output:

 equality with copy: 0 equality without copy: 1 

However, std :: vector provides equal output regardless of copy.

Debian 7 x86 GCC x86 32 bit Debug Qt 5.1.0 qmake spec linux-g ++

thanks for answers

+4
source share
2 answers

This is because QStringList is one of the implicit shared classes of Qt, which means that when you make a copy, you actually copy only the link to the contents of the list ("real" copying only happens when / if one of the objects changes).

If you want an iteration like you are here, you have to change the end () method with constEnd (), like this:

 QStringList::const_iterator it = list.constEnd(); if (b) { // 'static' to prevent optimization static QStringList copy = list; } --it; // 2 --it; // 1 --it; // 0 ++it; // 1 ++it; // 2 --it; // 1 ++it; // 2 ++it; // end return it == list.constEnd(); 

While the end () method returns an iterator, constEnd () (or cend ()) returns a const_iterator, so this is what you need to use in this case. There's an interesting article there if you want to explore more deeply:

http://doc.qt.digia.com/qq/qq12-qt4-iterators.html#implicitsharinganditerators

I hope this can help you.

+4
source
 QStringList::const_iterator it = list.end(); 

Be very careful in this call - this will result in a (possibly unwanted) disconnect. Use constEnd () if you don't want this. And, warning one more question, let me quote the docs :

Implicit sharing has a different meaning for STL-style iterators: you should not take a copy of a container, while non-constant iterators are active in that container. Java-style iterators do not suffer from this limitation.

+3
source

Source: https://habr.com/ru/post/1493354/


All Articles