[Development] Should QVariant be doing fuzzy comparisons on doubles?
André Pönitz
apoenitz at t-online.de
Fri Sep 23 19:45:18 CEST 2016
On Fri, Sep 23, 2016 at 11:22:08AM +0200, Olivier Goffart wrote:
> > There is not much of a choice. An equivalence relation is reflexive,
> > i.e. at least Foo(a) == Foo(a) must be true. Lacking the ability
> > to compare Foos, treating them all equal at least doesn't break the
> > relation.
>
> Why do we want that kind of mathematical purity?
Because that's the only sane way to avoid ugly surprises.
> This ensure we have the most useless operator==.
> Most of the code use it for stuff like that:
>
> void setFoo(const QVariant &foo) {
> if (foo != m_foo) {
> m_foo = foo;
> emit fooChanged();
> }
> }
That gives already "surprising" behaviour if fed with QChar('a') and
QString("a") in a row.
And it is "surprising" to a degree that I'd call it buggy.
> And suddenly returning always true if the variant has the same type will break
> this code. And i think will break most use case for QVariant::operator==
Most of the uses of QVariant::operator==() ARE ALREADY BROKEN, and will
not be fixable if people refuse to accept basic requirements.
> What use case did you have in mind where a reflexive relation is any usefull?
> There is the case of the key of a QHash or in a QSet, but even then i'm not
> sure it is wise that all QVariant of the same type map to the "same" value.
The discussion started with making QVariant ready for use in hashs.
> So let's be pragmatic here and do something usefull rather than something
> methematicaly correct, but useless and that break lot of code.
This "pragmatism" has already led to the current situation where
the number of items in a QMap with QVariant keys depend on the
order of insertion and other crap.
> Now that we have C++11 and we can use some expression SFINAE, we can do
> something like:
>
>
> template<class T>
> auto registerEqualityOperator()
> -> decltype(std::declval<T>() == std::declval<T>())
>
> Called from qRegisterMetaType, which automatically register the operator== if
> it exists.
>
>
> The QVariant::operator== could return false if none was registered. And
> possibly print a qWarning: "Attempting to compare two QVariant containing type
> 'Foo' which has no equality operation registered".
That would be ok to, but does not invalidate my point.
Andre'
More information about the Development
mailing list