Re: [Development] QHash iteration vs std::unordered_map
On 2017-04-20 13:18, Sergio Martins wrote: > On 2017-04-20 18:06, Matthew Woehlke wrote: >> for (auto i : qtEnumerate(my_hash)) >> do_stuff(i.key(), i.value()); > > That doesn't work with temporaries, does it ? No. Neither does std::add_const / qAsConst. > Maybe something to fix in the C++ language, since the usual > lifetime-extension tricks don't help in this case. There has been talk, but TTBOMK no concrete proposals yet. (IIRC the `register` proposal was published but the author decided not to present it yet.) -- Matthew ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QHash iteration vs std::unordered_map
On 2017-04-20 18:06, Matthew Woehlke wrote: On 2017-04-16 10:44, Corentin wrote: If you want the same behavior, you can create a proxy for your associative container instance, with a custom iterator whose operator*() returns a std pair ( or a QPair ) - quite a bit of boilterplate code. ...or use https://github.com/Kitware/qtextensions/blob/master/core/qtEnumerate.h. Rather than returning a pair (which may add overhead), it creates a proxy that just returns the iterator, so you can write: for (auto i : qtEnumerate(my_hash)) do_stuff(i.key(), i.value()); That doesn't work with temporaries, does it ? Maybe something to fix in the C++ language, since the usual lifetime-extension tricks don't help in this case. Regards, -- Sérgio Martins | sergio.mart...@kdab.com | Senior Software Engineer Klarälvdalens Datakonsult AB, a KDAB Group company Tel: Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322) KDAB - The Qt, C++ and OpenGL Experts ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QHash iteration vs std::unordered_map
On 2017-04-16 10:44, Corentin wrote: > If you want the same behavior, you can create a proxy for your associative > container instance, with a custom iterator whose operator*() returns a std > pair ( or a QPair ) - quite a bit of boilterplate code. ...or use https://github.com/Kitware/qtextensions/blob/master/core/qtEnumerate.h. Rather than returning a pair (which may add overhead), it creates a proxy that just returns the iterator, so you can write: for (auto i : qtEnumerate(my_hash)) do_stuff(i.key(), i.value()); As a plus, `key()` and `value()` are much more readable than `first` and `second`. -- Matthew ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QHash iteration vs std::unordered_map
On Tuesday 18 April 2017 10:52:47 Olivier Goffart wrote: > On Montag, 17. April 2017 18:48:26 CEST Marc Mutz wrote: > > On Monday 17 April 2017 18:08:20 Thiago Macieira wrote: > > > Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz > > escreveu: > > > > The problem with QT_STRICT_ITERATORS is _not_ that they are changing > > > > begin() and end(), > > > > > > Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not > > > in other, regardless of exporting or not. > > > > Why? > > ODR violation is an undefined behaviour. > (Technically, this is also the case across library boundaries) If QT_STRICT_ITERATORS (as-is) is an ODR violation, and technically, it is, then so is #ifdef Q_COMPILER_... over member functions, or QT_NO_CAST_FROM_ASCII. However, we'd be screwed if any compiler started to exploit that particular UB. So, there's nothing out of the ordinary with QT_STRICT_ITERATORS itself. Maybe there was in the past, but not in its current state. In its current state, the problems with QT_STRICT_ITERATORS are _solely_ the two I mentioned, and they affect all member-function-ifdef'ery, be it about iterators, conversions, or c++ features, in the same way. Just try to compile QtCore with QT_NO_CAST_FROM_ASCII and watch the carnage that surely ensues. We can turn a blind eye on the issue, but this wholesale exporting of non- polymophic classes will bite us over and over again, until the naysayers will have learned, too. 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] QHash iteration vs std::unordered_map
On Montag, 17. April 2017 18:48:26 CEST Marc Mutz wrote: > On Monday 17 April 2017 18:08:20 Thiago Macieira wrote: > > Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz escreveu: > > > The problem with QT_STRICT_ITERATORS is _not_ that they are changing > > > begin() and end(), > > > > Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in > > other, regardless of exporting or not. > > Why? ODR violation is an undefined behaviour. (Technically, this is also the case across library boundaries) ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QHash iteration vs std::unordered_map
Em segunda-feira, 17 de abril de 2017, às 09:48:26 PDT, Marc Mutz escreveu: > On Monday 17 April 2017 18:08:20 Thiago Macieira wrote: > > Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz escreveu: > > > The problem with QT_STRICT_ITERATORS is _not_ that they are changing > > > begin() and end(), > > > > Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in > > other, regardless of exporting or not. > > Why? Well, now it can, because of this: iterator begin(iterator = iterator()) Q_DECL_NOTHROW { return data(); } iterator end(iterator = iterator()) Q_DECL_NOTHROW { return data() + size; } Because of the parameter, the non-strict version calls begin(T*), whereas the strict one calls begin(QTypedArrayData::iterator). Those are two different functions, with different name manglings. When they are emitted out-of-line and merged at link time, you'll have two copies, not one. The difference is how the ABI returns the return value: a QTypedArrayData::iterator is returned by implicit reference, whereas a pointer is returned by value. In the former case, the caller passes an implicit parameter to the storage area for the called function. In the latter, there is no parameter. So if the two functions had the same parameters (and thus the same mangling), the caller of the non-strict would not pass anything for the first parameter, causing the called strict begin() function to dereference an uninitialised pointer. -- 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] QHash iteration vs std::unordered_map
On Monday 17 April 2017 18:08:20 Thiago Macieira wrote: > Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz escreveu: > > The problem with QT_STRICT_ITERATORS is _not_ that they are changing > > begin() and end(), > > Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in > other, regardless of exporting or not. Why? -- 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] QHash iteration vs std::unordered_map
Em segunda-feira, 17 de abril de 2017, às 00:30:23 PDT, Marc Mutz escreveu: > The problem with QT_STRICT_ITERATORS is _not_ that they are changing begin() > and end(), Actually, it was. You can't use QT_STRICT_ITERATORS in one TU and not in other, regardless of exporting or not. -- 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] QHash iteration vs std::unordered_map
On Monday 17 April 2017 00:59:55 Thiago Macieira wrote: > Em domingo, 16 de abril de 2017, às 15:16:54 PDT, Mark Gaiser escreveu: > > Ohh, that's great! > > > > > > > > One question. Would it be possible and sane to - by default - provide > > it as the patch implements it there, but with the addition of a define > > that can influence the behavior of the iterators? > > Most llikely no. Just look at the problem that QT_STRICT_ITERATORS causes. > We shouldn't make the same mistake again. The problem with QT_STRICT_ITERATORS is _not_ that they are changing begin() and end(), but that a) classes that shouldn't be (non-polymorphic ones), are exported, thus breaking patterns that are deeply ingrained in C++ developers (inline function no longer are inline, e.g.) and b) that classes that shouldn't be (non-polymorphic ones with public dtor), are inherited. _These_ are the things that need fixing, not QT_STRICT_ITERATORS, or a hypothetical QT_STL_COMPATIBLE_ITERSTORS, even though I consider the former, too, a kludge. 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] QHash iteration vs std::unordered_map
Em domingo, 16 de abril de 2017, às 15:16:54 PDT, Mark Gaiser escreveu: > Ohh, that's great! > > One question. Would it be possible and sane to - by default - provide > it as the patch implements it there, but with the addition of a define > that can influence the behavior of the iterators? Most llikely no. Just look at the problem that QT_STRICT_ITERATORS causes. We shouldn't make the same mistake again. -- 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] QHash iteration vs std::unordered_map
Em domingo, 16 de abril de 2017, às 15:09:16 PDT, Mark Gaiser escreveu: > On Sun, Apr 16, 2017 at 5:53 PM, Thiago Macieira > >wrote: > > Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu: > >> That again makes me wonder, why did Qt diverge from that? > > > > We didn't diverge. We never had that. The Qt style predates the Standard > > Library having relevance in Qt. When the first QHash-like class was added, > > it was just like that. > > With regards to QHash vs std::unordered_map, yes. > But STL also has std::map which certainly predates Qt and also gives > back an std::pair. I was referring to std::map and QDict. -- 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] QHash iteration vs std::unordered_map
On Sun, Apr 16, 2017 at 9:48 PM, Samuel Gaistwrote: > >> On 16 Apr 2017, at 17:53, Thiago Macieira wrote: >> >> Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu: >>> That again makes me wonder, why did Qt diverge from that? >> >> We didn't diverge. We never had that. The Qt style predates the Standard >> Library having relevance in Qt. When the first QHash-like class was added, it >> was just like that. >> >> Also remember that at the time, you wouldn't think of a Standard Library >> associative container as such. It was just a sequential container that held a >> std::pair, with some convenience functions for searching the first of the >> pair. >> Returning a pair was a consequence of that. I don't know if it was >> intentional >> thinking, or it just happened. >> >>> And... if Qt plans to change it in Qt6? >> >> No, cannot due to source compatibility. Ever. >> >> -- >> 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 >> > > Hi, > > Just in case, there’s a work in progress at > > https://codereview.qt-project.org/#/c/151511/ > > to add these "missing" iterators to QHash and QMap. Ohh, that's great! One question. Would it be possible and sane to - by default - provide it as the patch implements it there, but with the addition of a define that can influence the behavior of the iterators? For instance a "QT_STL_COMPATIBLE_ITERATORS" (just made that up, doesn't exist) when defined gives the iterators begin/constBegin/cbegin/enc/constEnd/cend STL compatible output (so give an std::pair with key and value)? When not defined (the default i guess) it falls back to what Qt uses now. Providing this option makes the Qt containers easier to use with STL algorithms. ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QHash iteration vs std::unordered_map
On Sun, Apr 16, 2017 at 5:53 PM, Thiago Macieirawrote: > Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu: >> That again makes me wonder, why did Qt diverge from that? > > We didn't diverge. We never had that. The Qt style predates the Standard > Library having relevance in Qt. When the first QHash-like class was added, it > was just like that. With regards to QHash vs std::unordered_map, yes. But STL also has std::map which certainly predates Qt and also gives back an std::pair. > > Also remember that at the time, you wouldn't think of a Standard Library > associative container as such. It was just a sequential container that held a > std::pair, with some convenience functions for searching the first of the > pair. > Returning a pair was a consequence of that. I don't know if it was intentional > thinking, or it just happened. > >> And... if Qt plans to change it in Qt6? > > No, cannot due to source compatibility. Ever. > > -- > 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 ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QHash iteration vs std::unordered_map
> On 16 Apr 2017, at 17:53, Thiago Macieirawrote: > > Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu: >> That again makes me wonder, why did Qt diverge from that? > > We didn't diverge. We never had that. The Qt style predates the Standard > Library having relevance in Qt. When the first QHash-like class was added, it > was just like that. > > Also remember that at the time, you wouldn't think of a Standard Library > associative container as such. It was just a sequential container that held a > std::pair, with some convenience functions for searching the first of the > pair. > Returning a pair was a consequence of that. I don't know if it was intentional > thinking, or it just happened. > >> And... if Qt plans to change it in Qt6? > > No, cannot due to source compatibility. Ever. > > -- > 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 > Hi, Just in case, there’s a work in progress at https://codereview.qt-project.org/#/c/151511/ to add these "missing" iterators to QHash and QMap. Cheers, Samuel signature.asc Description: Message signed with OpenPGP ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development
Re: [Development] QHash iteration vs std::unordered_map
Em domingo, 16 de abril de 2017, às 08:05:21 PDT, Mark Gaiser escreveu: > That again makes me wonder, why did Qt diverge from that? We didn't diverge. We never had that. The Qt style predates the Standard Library having relevance in Qt. When the first QHash-like class was added, it was just like that. Also remember that at the time, you wouldn't think of a Standard Library associative container as such. It was just a sequential container that held a std::pair, with some convenience functions for searching the first of the pair. Returning a pair was a consequence of that. I don't know if it was intentional thinking, or it just happened. > And... if Qt plans to change it in Qt6? No, cannot due to source compatibility. Ever. -- 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] QHash iteration vs std::unordered_map
On Sun, Apr 16, 2017 at 4:44 PM, Corentinwrote: > Funny, a friend at kdab asked me about that exact question a few minutes > ago. > The reason for the difference is most certainly an historical one ( and > can't be changed because it would break quite a bit of code ). > > If you want the same behavior, you can create a proxy for your associative > container instance, with a custom iterator whose operator*() returns a std > pair ( or a QPair ) - quite a bit of boilterplate code. It probably does come down to historic reasons, but that would be strange as well. I doubt that the C++ committee changed what is returned by operator*() (correct me if i'm wrong) so i'm inclined to think that the std:: stuff is returning it as an std::pair for quite a while now. That again makes me wonder, why did Qt diverge from that? And... if Qt plans to change it in Qt6? > > > > > Le dim. 16 avr. 2017 à 15:57, Mark Gaiser a écrit : >> >> Hi, >> >> Take this simple example: >> >> QHash test = { >> {10, "aaa"}, >> {20, "bbb"}, >> {30, "ccc"} >> }; >> >> for (const auto : qAsConst(test)) { >> qDebug() << entry; >> } >> >> It returns: >> "aaa" >> "ccc" >> "bbb" >> >> and the std::unordered_map version: >> std::unordered_map test = { >> {10, "aaa"}, >> {20, "bbb"}, >> {30, "ccc"} >> }; >> >> for (const auto : test) { >> qDebug() << entry; >> } >> >> it returns: >> std::pair(30,"ccc") >> std::pair(10,"aaa") >> std::pair(20,"bbb") >> >> As you can see, the QHash iteration directly returns the value. The >> std::unordered_map returns a std::par with the key and value for the >> current iteration (in it's respective first and second members). Both >> approaches probably have arguments in favor and against. What i'm >> curious about is why there is a difference at all? >> >> I'm curious because the behavior is a bit unexpected when compared to >> std::unordered_map. I would have guessed QHash to follow the same >> logic as std::unordered_map, only with a Qt syntax. So for instance a >> return of QPair(...), not the value directly. >> >> Thanks, >> Mark >> ___ >> 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] QHash iteration vs std::unordered_map
Funny, a friend at kdab asked me about that exact question a few minutes ago. The reason for the difference is most certainly an historical one ( and can't be changed because it would break quite a bit of code ). If you want the same behavior, you can create a proxy for your associative container instance, with a custom iterator whose operator*() returns a std pair ( or a QPair ) - quite a bit of boilterplate code. Le dim. 16 avr. 2017 à 15:57, Mark Gaisera écrit : > Hi, > > Take this simple example: > > QHash test = { > {10, "aaa"}, > {20, "bbb"}, > {30, "ccc"} > }; > > for (const auto : qAsConst(test)) { > qDebug() << entry; > } > > It returns: > "aaa" > "ccc" > "bbb" > > and the std::unordered_map version: > std::unordered_map test = { > {10, "aaa"}, > {20, "bbb"}, > {30, "ccc"} > }; > > for (const auto : test) { > qDebug() << entry; > } > > it returns: > std::pair(30,"ccc") > std::pair(10,"aaa") > std::pair(20,"bbb") > > As you can see, the QHash iteration directly returns the value. The > std::unordered_map returns a std::par with the key and value for the > current iteration (in it's respective first and second members). Both > approaches probably have arguments in favor and against. What i'm > curious about is why there is a difference at all? > > I'm curious because the behavior is a bit unexpected when compared to > std::unordered_map. I would have guessed QHash to follow the same > logic as std::unordered_map, only with a Qt syntax. So for instance a > return of QPair(...), not the value directly. > > Thanks, > Mark > ___ > 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
[Development] QHash iteration vs std::unordered_map
Hi, Take this simple example: QHashtest = { {10, "aaa"}, {20, "bbb"}, {30, "ccc"} }; for (const auto : qAsConst(test)) { qDebug() << entry; } It returns: "aaa" "ccc" "bbb" and the std::unordered_map version: std::unordered_map test = { {10, "aaa"}, {20, "bbb"}, {30, "ccc"} }; for (const auto : test) { qDebug() << entry; } it returns: std::pair(30,"ccc") std::pair(10,"aaa") std::pair(20,"bbb") As you can see, the QHash iteration directly returns the value. The std::unordered_map returns a std::par with the key and value for the current iteration (in it's respective first and second members). Both approaches probably have arguments in favor and against. What i'm curious about is why there is a difference at all? I'm curious because the behavior is a bit unexpected when compared to std::unordered_map. I would have guessed QHash to follow the same logic as std::unordered_map, only with a Qt syntax. So for instance a return of QPair(...), not the value directly. Thanks, Mark ___ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development