[Development] How qAsConst and qExchange lead to qNN
ulf.hermann at qt.io
Fri Nov 11 09:35:27 CET 2022
There is an undeniable benefit of _offering_ QSpan, QStringView, and
generator APIs in a few relevant cases:
1. Users want to pass a "foreign" container to a Qt function that
doesn't only store it as QList or QString. It might merely iterate it or
store it as something else.
2. Assume a container that isn't internally stored as QList or QString,
but is returned from a Qt function. Users want to use that thing as
something else than QString or QList. For example they might merely
iterate it or store its contents in a "foreign" container.
In those cases, using QList or QString as transfer mechanism induces an
unnecessary deep copy.
All other cases look much fuzzier to me. QSpan or QStringView (or a
generator) may be beneficial or detrimental there, depending on exact
usage pattern. The cost we're avoiding is mostly the reference count, a
far cry from a deep copy. On the flip side we're introducing complex
life time problems that will lead to hard to find memory management
defects. I suggest we look at this from the perspective of a _user_ of
Qt. I'm pretty sure you can all imagine which problem a user would
So, I suggest we add those "view" APIs to the cases where they provide a
clear benefit. For methods that return a span/view/generator, we should
always offer a safe alternative that returns an owning container. The
naming convention should be:
1. Use overloads for methods that take views or spans. In new API we can
omit the methods that take owning containers. If the overload set grows
out of hand, don't add the view/span alternative until we can remove
something. By Thiago's argument, that means not to convert existing
methods to QStringView for now.
2. Use the postfix "View", "Span" or "Generator" for methods that return
views, spans or generators rather than owning containers. This way it's
harder for users to mess up the life time.
More information about the Development