Re: [Development] RFC: Containers member functions for algorithm
> On Mar 24, 2017, at 10:33 PM, André Pönitzwrote: > > On Fri, Mar 24, 2017 at 04:25:34PM +, Corentin wrote: >> Is std::algo(std::begin(container), std::end(container) ... ) troublesome >> enough that it warrants a wrapper ? > > Yes. > > 1. It is more to read, and more to verify during reading, e.g. > that bother 'container' are the same. > > This typically implies that 'container' is just a simple > identifier for a local variable (i.e. usuall an extra line for > a definition) or a member of the current object (rare). > > Even seeing > > std::algo(std::begin(foo), std::end(foo) ... ) > > *verbatim* with a plain 'foo' does not guarantee that both > 'foo' refer to the same container, i.e. potentially needs > verification when bug hunting. > > For > > std::algo(std::begin(foo()), std::end(foo()) ... ) > > chances are high that it is wrong. Except when it isn't. > But for that you need to consult the declaration, and > even possibly the implementation of 'foo'. > > > 2. It more to type. > > std::algo(std::begin(container), std::end(container) ... ) > > vs > > foo::algo(container, ... ) > > Depending on your project's coding style there are additional > complications, e.g. that the ~55 chars of the first are 'a lot' > in a 80 char-per-line setup. And begin and end are not the only things that can be gotten rid of. The back_inserters you need for things like transform and copy_if are noise for the simple/common case, and I’ve seen a few patches already that forgot the erase after remove_if. > >> Your last example is simplified by the Library Fundamentals TS >> https://rawgit.com/cplusplus/fundamentals-ts/v2/fundamentals-ts.html#container.erasure >> erase_if(std::begin(myList), std::end(myList), [&](const auto ) { >> elem.field > someValue; }); > > 100 chars, vs 70 chars for a no-begin-end-cluttered > > erase_if(myList, [&](const auto ) { elem.field > someValue; }); > > and some hope that it going from 'myList' to 'myList()' is really > just two chars change. > > Not Nice (TM). > > Andre' > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Eike Ziller Principal Software Engineer The Qt Company GmbH Rudower Chaussee 13 D-12489 Berlin eike.zil...@qt.io http://qt.io Geschäftsführer: Mika Pälsi, Juha Varelius, Mika Harjuaho Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 144331 B ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
On 25 March 2017 at 07:00, Kevin Koflerwrote: > Michael Winkelmann wrote: >> 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. > > Why is that bad? It is convenient and object-oriented. Moving everything to > freestanding functions goes against the principles of OOP. "OO was hip in the 80s and 90s, but its time we moved beyond!". >From http://www.boost.org/doc/libs/1_63_0/libs/graph/doc/faq.html item 3, last paragraph. I'm not advocating for free functions, i really hate them. I have been working with boost graph recently and find this technique awful to write, awful to read and counter intuitive. I hope Qt won't become like boost. Chris > > That said, even freestanding functions would be better than the current > boilerplate myContainer.begin(), myContainer.end() copypasta. > > Kevin Kofler > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
On Fri, Mar 24, 2017 at 04:25:34PM +, Corentin wrote: > Is std::algo(std::begin(container), std::end(container) ... ) troublesome > enough that it warrants a wrapper ? Yes. 1. It is more to read, and more to verify during reading, e.g. that bother 'container' are the same. This typically implies that 'container' is just a simple identifier for a local variable (i.e. usuall an extra line for a definition) or a member of the current object (rare). Even seeing std::algo(std::begin(foo), std::end(foo) ... ) *verbatim* with a plain 'foo' does not guarantee that both 'foo' refer to the same container, i.e. potentially needs verification when bug hunting. For std::algo(std::begin(foo()), std::end(foo()) ... ) chances are high that it is wrong. Except when it isn't. But for that you need to consult the declaration, and even possibly the implementation of 'foo'. 2. It more to type. std::algo(std::begin(container), std::end(container) ... ) vs foo::algo(container, ... ) Depending on your project's coding style there are additional complications, e.g. that the ~55 chars of the first are 'a lot' in a 80 char-per-line setup. > Your last example is simplified by the Library Fundamentals TS > https://rawgit.com/cplusplus/fundamentals-ts/v2/fundamentals-ts.html#container.erasure > erase_if(std::begin(myList), std::end(myList), [&](const auto ) { > elem.field > someValue; }); 100 chars, vs 70 chars for a no-begin-end-cluttered erase_if(myList, [&](const auto ) { elem.field > someValue; }); and some hope that it going from 'myList' to 'myList()' is really just two chars change. Not Nice (TM). Andre' ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
Michael Winkelmann wrote: > 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. Why is that bad? It is convenient and object-oriented. Moving everything to freestanding functions goes against the principles of OOP. That said, even freestanding functions would be better than the current boilerplate myContainer.begin(), myContainer.end() copypasta. Kevin Kofler ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
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 https://rawgit.com/cplusplus/fundamentals-ts/v2/fundamentals-ts.html#container.erasure erase_if(std::begin(myList), std::end(myList), [&](const auto ) { 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 Goffarta é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 , auto ){ return a.member < b.member; }); > > if (myList.contains([](const auto ){ return elem.id == value; > })) >doSomething(); > > myList.removeIf([&](const auto ) { 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.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 ) > { 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 ) { return elem.foo == bar; }); > if (it !=
Re: [Development] RFC: Containers member functions for algorithm
On quinta-feira, 23 de março de 2017 02:36:06 PDT Marc Mutz wrote: > Second, that member functions always get their *this argument passed by > reference. A free function can take the argument by value instead. The example for this is actually in the other thread: QStringView::indexOf(). If you write: QStringView(u"Hello").indexOf(u'l'); The compiler has to load the address of the u"Hello" literal and the size (5), then save them to a temporary in the stack, then load the address of that temporary into the register and call the target function. A free function passing QStringView by value would (not on Windows[*]) pass the address of the literal and the length as parameters. Compare the f and g functions in https://godbolt.org/g/lV5Swu. How to solve this? Easy, inline indexOf redirecting the call to the free function, as in https://godbolt.org/g/GFRxKU. [*] Why not on Windows? Change the compiler to Clang and add -target x86_64-mingw you'll see that now f and g are identical in both cases. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
On quinta-feira, 23 de março de 2017 00:32:14 PDT 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: [cut] I like the initiative, but the commenters have a good point to about free functions. We can probably find a balance between them, which functions are so common that should be members, and which ones we ought to leave free. If you can start throwing the idea around and see what you can come up with, we'll take it step-by-step. If not, let's have some time for this during QtCS later this year. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
Il 23/03/2017 10:36, Marc Mutz ha scritto: > Exactly. Bring back qSort(Container &), calling std::sort(std::begin(c), > std::end(c)). But leave the container interface alone. This could be done "right now" if we add them in a separate namespace. Whether changing qSort itself -- back in the day I didn't because it was a SIC. I would still be keen to call it a semi-unacceptable SIC today, even after 9 minor versions, as people do not compile code with deprecation warnings (*), so they have no idea that qSort should've not be used... (*) we had discussion at the last QtCS, and I had to write patches and a blog post about this, because our users didn't know! Cheers, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (UK) Ltd., a KDAB Group company | Tel: UK +44-1625-809908 KDAB - Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
I agree, but Marc actually just said that creator could suggest functions with signature f(T) when one presses . after an object o of type T. That's not the same as allowing the syntax o.f() to call f(o). On 23.03.2017 11:51, Konrad Rosenbaum wrote: > On Thursday, March 23, 2017 10:36:06 Marc Mutz wrote: >> There're >> proposals floating around for years to make o.f() fall back to f(o) for std >> C++. > Those are a lot more pain than you'd think! This construct already exists in > C# (static extension classes/methods) and it is causing major headaches there > - depending on your using statements (equiv. of #include) what looks like a > simple method call can mean totally different things or not work at all! A > change in a different section of the class that necessitates an additional > using directive may cause all kinds of mayhem. It is a nightmare if you have > to diagnose problems. > > In short: the recommendation in the C# world is: "do not use them unless you > absolutely positively have no other choice." We should take that as a warning. > > > Konrad > > > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Viktor Engelmann Software Engineer The Qt Company GmbH Rudower Chaussee 13 D-12489 Berlin viktor.engelm...@qt.io +49 151 26784521 http://qt.io Geschäftsführer: Mika Pälsi, Juha Varelius, Mika Harjuaho Sitz der Gesellschaft: Berlin Registergericht: Amtsgericht Charlottenburg, HRB 144331 B ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
On Thursday, March 23, 2017 10:36:06 Marc Mutz wrote: > There're > proposals floating around for years to make o.f() fall back to f(o) for std > C++. Those are a lot more pain than you'd think! This construct already exists in C# (static extension classes/methods) and it is causing major headaches there - depending on your using statements (equiv. of #include) what looks like a simple method call can mean totally different things or not work at all! A change in a different section of the class that necessitates an additional using directive may cause all kinds of mayhem. It is a nightmare if you have to diagnose problems. In short: the recommendation in the C# world is: "do not use them unless you absolutely positively have no other choice." We should take that as a warning. Konrad signature.asc Description: This is a digitally signed message part. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
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 , auto ){ return a.member < b.member; }); > > if (myList.contains([](const auto ){ return elem.id == value; })) >doSomething(); > > myList.removeIf([&](const auto ) { 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.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 ) > { 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 ) { 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.winkelm...@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 --- ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
On 2017-03-23 11:01, Ville Voutilainen wrote: On 23 March 2017 at 11:36, Marc Mutzwrote: That said, there's a reason why there's no std::sort(Container &). It's because you need Concepts to disambiguate the various overloads. Well, that and because Eric Niebler doesn't manage to limit the scope of his range proposals. The TS proposal is quite tightly scoped. It doesn't have range views and range actions, for instance. I was referring to the | overloading, in particular. Time to look at it once more, then. :) Thanks, Marc ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
On 23 March 2017 at 11:36, Marc Mutzwrote: > That said, there's a reason why there's no std::sort(Container &). It's > because you need Concepts to disambiguate the various overloads. Well, that > and because Eric Niebler doesn't manage to limit the scope of his range > proposals. The TS proposal is quite tightly scoped. It doesn't have range views and range actions, for instance. > matters whether a function is a member or a free function. There're proposals > floating around for years to make o.f() fall back to f(o) for std C++. Ville > can probably say more about the status of these. This is a problem that can be That proposal was rejected, whether it will come back in some form is for the moment unknown. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
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 Goffartwrote: > 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 , auto ){ return a.member < b.member; }); > > if (myList.contains([](const auto ){ return elem.id == value; })) >doSomething(); > > myList.removeIf([&](const auto ) { 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.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 ) > { 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 ) { 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@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
On Thursday 23 March 2017 09:27:53 Eike Ziller wrote: > I do not think that these belong into the API of the containers though, or > at least if (some of) this API gets into the containers itself, the > implementation should just call generic functions. There is no reason why > the convenience should be restricted to the Qt containers, why > transforming a QVector should be convenient but not transforming a > std::vector. Adding functions instead of API to the containers also avoids > bloating the API of the containers, and makes the convenience completely > optional. Exactly. Bring back qSort(Container &), calling std::sort(std::begin(c), std::end(c)). But leave the container interface alone. Everyone probably comes up with these (I posted mine in the QList thread: https://github.com/KDE/libkleo/blob/2fe48b77ba61fada80eaace8cb71dd0fd1326). That said, there's a reason why there's no std::sort(Container &). It's because you need Concepts to disambiguate the various overloads. Well, that and because Eric Niebler doesn't manage to limit the scope of his range proposals. Anyway, I gave my opinion, incl. technical reasons why using member functions for this is a bad idea on Gerrit. I only want to add two things I did not mention there: First, that one of the usual reasons given for preferring member functions over free functions, discoverability, is a tool problem, and should be solved in the tools. Include free functions in the .-completion and it no longer matters whether a function is a member or a free function. There're proposals floating around for years to make o.f() fall back to f(o) for std C++. Ville can probably say more about the status of these. This is a problem that can be solved now in QtCreator and doesn't require adding more API mistakes. Second, that member functions always get their *this argument passed by reference. A free function can take the argument by value instead. It probably doesn't matter much for inline methods. But Chandler has used this example in his compiler talks as an example where a seemingly innocuous change (free to member function) can make the compiler's job much harder, due to the involvement of memory. Thanks, Marc -- Marc Mutz| Senior Software Engineer KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company Tel: +49-30-521325470 KDAB - The Qt, C++ and OpenGL Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
> On Mar 23, 2017, at 8:32 AM, Olivier Goffartwrote: > > 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 , auto ){ return a.member < b.member; }); > > if (myList.contains([](const auto ){ return elem.id == value; })) > doSomething(); > > myList.removeIf([&](const auto ) { 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.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 personally would not want to code without these anymore, and would be very glad if someone put similar things into Qt :) I do not think that these belong into the API of the containers though, or at least if (some of) this API gets into the containers itself, the implementation should just call generic functions. There is no reason why the convenience should be restricted to the Qt containers, why transforming a QVector should be convenient but not transforming a std::vector. Adding functions instead of API to the containers also avoids bloating the API of the containers, and makes the convenience completely optional. > 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 ) > { 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 ) { 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 Using functions instead of adding API to the containers has potential to greatly reduce the bike-shedding. Just add one function that returns a pointer, and another one that returns the iterator, without the fear of bloating the API of every container class. Br, Eike > Regards > -- > Olivier > > Woboq - Qt services and support - https://woboq.com - https://code.woboq.org > ___ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] RFC: Containers member functions for algorithm
Hi, I love this idea and how it goes into the direction of making life easier (more convenient) for developers. Simon > On 23 Mar 2017, at 08:32, Olivier Goffartwrote: > > 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 , auto ){ return a.member < b.member; }); > > if (myList.contains([](const auto ){ return elem.id == value; })) > doSomething(); > > myList.removeIf([&](const auto ) { 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.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 ) > { 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 ) { 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@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development