[Development] RFC: Containers member functions for algorithm
Philippe
philwave at gmail.com
Thu Mar 23 10:50:03 CET 2017
I hardly imagine a "container" api without a "contains()" member. What I
would call good sense. Qt already has this, std not.
The other member that makes sense, if "indexOf()"... Qt already has this.
For the rest, free functions provide more flexibility.
>> I realize that QtCreator already has helper functions:
>>https://code.woboq.org/qt5/qt-creator/src/libs/utils/algorithm.h.html
Similar convenience wrappers are found in many applications...
It would not harm to have such wrappers in Qt.
Philippe
On Thu, 23 Mar 2017 08:32:14 +0100
Olivier Goffart <olivier at woboq.com> wrote:
> Hi everyone,
>
> I have been wondering if we should enhance Qt container with member functions
> to help using some of the standard algorithm.
> a peace of code is better than many words. We would be able to do:
>
> myList.sort();
> //or
> myList.sort([](auto &a, auto &b){ return a.member < b.member; });
>
> if (myList.contains([&value](const auto &elem){ return elem.id == value; }))
> doSomething();
>
> myList.removeIf([&](const auto &elem) { elem.field > someValue; })
>
>
> And these are a tad more convenient than using the standard library directly.
> Compare to:
> myList.erase(std::remove_if(myList.begin(), myList.end(),
> [&](const auto &elem) { elem.field > someValue; }),
> myList.end());
>
> Of course, myList can be a QList, a QVector, or a QVarLenghtArray
>
> Here is an overview in how this could be implemented, should we want this:
> https://codereview.qt-project.org/#/c/189313/
>
>
> Anyway, before I continue working on this patch, I want to know if this is
> even something what the Qt Project wants.
>
> The reason we would want it are obvious: convenience.
>
> In the mean time, the standard is working on the so called range library. So
> in C++20, you could maybe just write std::sort(myList).
> But that's in the far future, and I want to be able to use it now.
> There are already convenient range libraries that makes things convenient
> available on github, but that's another dependency and the compatibility
> guarantee are not the same.
>
>
> The reason we would not want this is because this makes our containers too
> convenient. The implementation of QVector is inferior to the one of
> std::vector. (for example, it cannot contains move-only types).
> Right now, it is quite easy to replace QVector by std::vector. But adding nice
> feature to QVector may mean a reason to keep QVector longer in Qt6 instead of
> changing to standard containers.
>
> Marc already expressed his opinion on the gerrit change, pointing out that we
> deprecated qSort and the qt algorithm for a reason: the quality of the std
> algorithm was better than the naive implementation in Qt. However this is just
> a helper around the std algorithm implementation.
>
>
> Why did we not added these function already in Qt 4.0? I was not there yet,
> but I believe this might have been for technical reason: MSVC 6 was still
> supported until Qt 4.5, which mans no template member functions.
> Also sort needs an operator<, and non-template function might be instantiated
> even if not used.
>
> So with this mail I would like to know what you think. If you think this is a
> good idea or a terrible one.
>
>
> Once we agreed the general idea is good, we can go into the details of the API
> or implementation.
>
> On this WIP patch, I only took the algorithm that were most used within Qt and
> QtCreator. I realize that QtCreator already has helper functions:
> https://code.woboq.org/qt5/qt-creator/src/libs/utils/algorithm.h.html
> That's I think one proof that shows that this would be useful.
>
> I am wondering if findIf shoud return a pointer or an iterator.
> Returning a pointer allow things like
> if (auto *elem = myContainer.findIf([&](const auto &elem)
> { return elem.foo == bar; }))
> elem->plop = myPlop;
>
> But does not work well if you want to find-then-remove:
> auto it = std::find(myContainer.begin(), myContainer.end(),
> [&](const auto &elem) { return elem.foo == bar; });
> if (it != myContainer.end()) {
> myResult = *it;
> myContainer.erase(it); // not possible if 'it' was a pointer
> }
>
> So I'm afraid there will be much discussions and bike-shedding
>
> Regards
> --
> Olivier
>
> Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development
More information about the Development
mailing list