[Development] RFC: Containers member functions for algorithm
Olivier Goffart
olivier at woboq.com
Thu Mar 23 08:32:14 CET 2017
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
More information about the Development
mailing list