Marc Mutz wrote: > I was replying to Kevin. QModelIndex exactly fits his complaints about > const-&: > > It's a reference used in interfaces. As soon as you store it, though, it > may become stale at the next opportunity (like when calling a virtual > function). You're supposed to store them in QPersistentModelIndex in that > case. But QPMI is extremely expensive. > > Compare that to: > > const std::vector<QFoo> & foos(); > > You can either assign the result to a const-& (=QModelIndex case), get max > performance, but suffer from possible invalidation if you call out to > unknown code. Or you store it in a copy, incurring the copy, but > insulating yourself from changes to the original object > (=QPersistentModelIndex case). > > They really are two instances of the same class of problem: dangling > references. And you cannot escape that problem. Not in C++, and not in > other imperative languages, either. If you replaced QMI with an int, as > you could, for QAbstractListModels, then you'd have exactly the same > problems of invalidation (who updates your int if the row it points to > gets removed?).
And my point is that in most cases, CoW avoids exactly that problem, allowing you to safely (and even thread-safely!) return newly-created data (i.e. NOT return a dangling reference), without having to deep-copy it. Model indexes are a different matter. > I don't like QList because only experts can tell which guarantees it > provides for any given type (can I keep references into the container > across appends?). Simply assume that you can't. > It's also the only container in the C++ world where iterator and reference > validity are not synonyms: An append where capacity() == size() > invalidates iterators in both QList modes, but only invalidates references > in vector-with- padding mode. Again: Consider references always invalidated. The fact that they sometimes happen to keep working is an implementation detail that must not be relied on. Would you want QList to go out of its way to invalidate references somehow (if, due to a performance optimization, the data did not actually move)? That would go against the very performance principles you are fighting for. Part of the concept of undefined behavior is that it may also appear to just work (and then it may also start breaking at any time). There is no guarantee that invoking undefined behavior will crash and burn, that would defeat the purpose of undefined behavior. So just consider working with dangling references to QList members after modifying the list to be undefined behavior. If you are keeping a reference to an element of QList or QVector across an insert / append / prepend / remove, you are doing something wrong! Those references are really only intended to be used in lines such as: myList[i] = foo; or at most in the equivalent of a "with" block in some higher-level languages, i.e., e.g.: { Foo &element = myList[i]; element.foo = foo; element.bar = bar; } (You can leave off the scope braces if you want, but my point is that at that point you should be done using element, so you may as well let it go out of scope.) Everything else is a blatant API abuse. > I don't like CoW because it creates long-range effects that are also the > underlying reason we don't like global variables. It also makes any > complexity specifications moot, because you never know whether you will > incur that extra O(N) detach. In many practical cases, the alternative is to ALWAYS deep-copy (plain assignment in STL, explicit clone() in Java or Python), so CoW will actually SAVE you many of those O(n) deep-copy operations. > I don't like QSharedPointer because it does nothing better, and lot of > things worse, than shared_ptr and was only added (long after > boost::shared_ptr and tr1::shared_ptr came into existence) because of an > overly strict sense of BC that extends beyond the Qt libraries (aka "we > can't use boost/std in our APIs"). I consider QSharedPointer good enough, and I really think a complete Qt class library should remain a goal. In particular, I also think QtAlgorithms should be undeprecated and extended with new algorithms. The goal should be that the average Qt-using developer should never have to use any STL class, and the Qt ones should have a friendlier API. This was already the case in QtAlgorithms compared to the STL algorithms, e.g., qSort had a convenient qSort(container) overload whereas std::sort requires you to write the ugly and redundant std::sort(container.begin(), container.end(), qLess<T>());. So switching to STL algorithms was a huge step backwards in API quality. The std::sort API is also symptomatic of the main design issue of the STL: The STL API is always optimized for the complex corner case (such as wanting to sort only an arbitrary subset of a container), neglecting the convenience overloads for the common case that will matter in >99% of the cases (sorting the whole container). (Having to pass qLess explicitly is another issue, but that one is mostly a backwards compatibility issue. The bigger issue is that std::sort(container) just does not exist, even if you want the operator< comparison function the STL defaults to.) So you end up with boilerplate .begin() and .end() calls all over the place. > As for why I am receiving such heat: I don't. It's the same couple of > persons every time that troll around. I should get better at not feeding > them, sure. I see only one person trolling and that's you. Everyone on this list knows that you love the STL and the new C++ language features in C++11 and newer and would like everyone to pick them up immediately, throw away everything else and do everything the C++11 way, which you consider the one right way. But things are simply not that black and white. We also all know that you want to do very complex things with containers that many people (even on this list!) did not even know existed, let alone would have expected someone to actually try to use. Please keep in mind that you are not the average Qt-using developer. > The wider C++ community ignores Qt, and I feel that's to the detriment of > both. I think Qt should ignore the "wider C++ community", too. The STL is really a completely different beast, we only share the language-level parts. > Some try to fork the project. Somebody forking the project is exactly what is going to happen if you throw away the very things that made people use Qt. Kevin Kofler _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development