[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.


More information about the Development mailing list