> On 12 Nov 2022, at 14:41, A. Pönitz <apoen...@t-online.de> wrote:
> 
> On Fri, Nov 11, 2022 at 09:35:27AM +0100, Ulf Hermann via Development wrote:
>> There is an undeniable benefit of _offering_ QSpan, QStringView, and
>> generator APIs in a few relevant cases:
> 
> This is true, but my problem with this is that already _offering_
> additional solutions does not come for free: It bloats the API,
> it bloats docs, introducing the first overload is SIC etc.


With QT_REMOVED_FROM we can remove the “first overload” problem, and replace 
QString with QAnyStringView.

We could use QAnyStringView  in e.g.. QFont::fromString or 
QPageRanges::fromString or QKeySequence::fromString (the obvious candidates in 
Qt Gui). And then I can write either of


fromString(“foo”);
fromString(u“foo”);
fromString(u"foo”_s);
fromString(stdString);
fromString(qString);

Is that not a good idea?

Perhaps it isn’t because there is now a fraction of our API that I can call 
that way, why for the vast majority I have to always use Qt::StringLiterals and 
call with a u”…”_s.

But how can we make progress with our API otherwise? Should we accept that we 
will never be able to call a QString-taking setter with u”…”?


>> 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.
> 
> Tradionally, we had QList as the (designed to be, and in practice also
> being) the "usually good enough for most uses" container, so in a /Qt/
> World, this "alien container" case /practically/ had no relevance,


I don’t think we can be certain that the amount of client code that use non-Qt 
containers and only deals with Qt containers at the API boundary is negligible. 
I would rather assume that only a minority of Qt applications *only* use Qt. 
The slice of the world that truly is a “Qt World” is perhaps rather small, 
while the majority of applications is a messy, organically grown mix of 
different frameworks and libraries. In those, most thing are alien to most 
other things, and interoperability on various levels is important.

So making it convenient for client code to use Qt APIs without having to deal 
with Qt containers has value. It is possible today - although perhaps 
under-documented, esp since we removed to/fromStdVector and to/fromStdList from 
Qt 6:

    setList({svector.cbegin(), svector.cend()});

This is not great, but as long as client code is anyway operating on owning 
containers, it’s perhaps as good as we can reasonably make it.


> The problem of regularly having to convert between Qt containers has been
> /introduced/ by people advocating QList uses by QVector, or std::vector.


Qt 3’s QValueList was implicitly constructible from std::list. We added it 
because people asked for easier integration of Qt with STL-using code.


>> 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.
> 
> This is pretty much the same problem: Standardizing on QString and QList
> as the "primary" containers avoids these problems on a large scale,
> and this overall gain outweighs the effect local micro-optimizations
> by far. The problem is that this (un-)balance is hard to communicate,
> as it is very easy to demonstrate that small, isolated uses of QString
> and QList are suboptimal, but the /overall/ benefit of a uniform
> approach only kicks in at "real world"-sized applications.



For applications that are not “pure Qt" applications - and I believe that is 
not an insignificant number, perhaps it’s even the majority - standardizing on 
Qt data types is simply not an option.

And Ulf’s case here is anyway that “there is no QList or QString” that is 
internally stored and that we just need to return. There might not even be any 
list-or string-like datastructure stored.

QItemSelectionModel doesn’t store a QList of selected indices. And yet 
QItemSelectionModel::selectedIndexes returns a QModelIndexList that is rather 
costly to create. An application that just wants to iterate over all selected 
indexes already has to pay an unnecessary cost. An application that then 
doesn’t use Qt containers in client code pays an extra cost on top.

I think it would be good if we could develop an API strategy that avoids that. 
Marc’s proposal of a Non-Owning Interface is already become manifest in 
QRegion::begin/end

https://doc.qt.io/qt-6/qregion.html#begin

allowing us to write


for (auto rect : region)
   doSomethingWith(rect);


(while QRegion::rects will have to create a QList even if there is only a 
single rect in the inline storage, which is then not a QList).


This is a *good* addition to Qt. I think we can make more such additions to Qt, 
in places where it makes a real difference for today’s client code using owning 
containers, and without changing the world.


Volker


_______________________________________________
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to