[Development] Question about QCoreApplicationData::*_libpaths
Kevin Kofler
kevin.kofler at chello.at
Fri Jan 22 01:13:06 CET 2016
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
More information about the Development
mailing list