[Development] RFC: Containers member functions for algorithm

Corentin corentin.jabot at gmail.com
Fri Mar 24 17:25:34 CET 2017

Is std::algo(std::begin(container), std::end(container) ... )  troublesome
enough that it warrants a wrapper ?

I have a few concerns:
  *  There is a large momentum behind the range proposal, and, if it wont
be in the standard before 2-4 years, I would expect the TS to be usable
long before that. For simple iterator abstractions like sort, find, etc,
range-v3 is certainly already pretty stable from an api standpoint.
 * C++17 bring parallel version of some algorithms.  I haven't look what
the requirements for a containers are to be compatible with those parallel
algorithms are, but I would prefer Qt to focus on that.
 * I'm afraid it won't be a popular opinion, but I wouldn't mind seing
constBegin() / constEnd()  deprecated, as they are redundant

Your last example is simplified by the Library Fundamentals TS
erase_if(std::begin(myList), std::end(myList), [&](const auto &elem) {
elem.field > someValue; });

If we fast forward to say, 5 years in the future, people will be confused
as to whether use std2::sort or Qt::sort (and if Qt::sort do not relies on
concept, it won't be as trivial to use )

If there is an immediate urgent need, a solution would be to have an api
that matches as close as possible the range TS, so that the migration path
can be as simple as changing "Qt" by "std2"

Le jeu. 23 mars 2017 à 08:32, Olivier Goffart <olivier at woboq.com> a écrit :

> 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
> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/development/attachments/20170324/1067641c/attachment.html>

More information about the Development mailing list