[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([](auto &a, auto &b){ return a.member < b.member; });

if (myList.contains([&value](const auto &elem){ return elem.id == value; }))

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; }),  

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:

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:
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


Woboq - Qt services and support - https://woboq.com - https://code.woboq.org

More information about the Development mailing list