[Development] RFC: Containers member functions for algorithm

Michael Winkelmann michael.winkelmann at qt.io
Thu Mar 23 11:45:46 CET 2017


The reason why STL is using free function is because it separates data
structures (aka containers) and algorithms.
A bad example what happens if you dont separate can be seen here:
https://www.imagemagick.org/api/Magick++/Image_8h_source.html

...and your data structure will be bloated with member functions.

Personally, I would prefer having some STL convenience wrapper functions
in Qt algorithm library.

Cheers


On 23.03.2017 08:32, Olivier Goffart 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

-- 
---
Michael Winkelmann
Qt Advisor

The Qt Company GmbH
Rudower Chaussee 13
D-12489 Berlin
michael.winkelmann at qt.io
+4915122973404
http://qt.io

Geschäftsführer: Mika Pälsi, Juha Varelius, Mika Harjuaho
Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 144331 B
---




More information about the Development mailing list