[Development] Converting types in Qt

Jędrzej Nowacki jedrzej.nowacki at digia.com
Thu Jul 17 14:38:40 CEST 2014


On Thursday 17 of July 2014 13:33:49 Daniel Teske wrote:
> On Thursday 17 Jul 2014 13:28:10 Jędrzej Nowacki wrote:
> > On Thursday 17 of July 2014 10:51:03 you wrote:
> > > QVariant::operator== is not symmetric
> > > 
> > >      QDateTime dateTime = QDateTime::currentDateTime();
> > >     
> > >     QTime time = dateTime.time();
> > >     
> > >     qDebug() << (QVariant(dateTime) == QVariant(time));
> > >     qDebug() << (QVariant(time) == QVariant(dateTime));
> > > 
> > > -->
> > > false
> > > true
> > 
> > We could make it symmetric, if you want.
> 
> A equals operator that is not symetric is broken. Such a class cannot be
> reliably used in std nor qt containers. Or do you know which way around,
> QList::contains uses the equals operation?

The example above shows what happens in case of a missing conversion, in this 
case QTime can be converted to QDateTime, but the QDateTime can not be 
converted to the QTime. Fail.

The operator was / is / will be broken. Even if we make it symmetric, it will 
remain conceptually broken. It should compare QVariants and then (maybe) the 
wrapped value, while currently it tries a fuzzy comparison of the wrapped 
value only.  It should look more or less like that:

bool operator ==(const QVariant &left, const QVariant& right)
{
	return left.userType() == right.userType() && 
!QMetaType::compare(left.constData(), rigth.constData(), left.userType());
}

To make it more ridiculous, currently it would not work as QMetType::compare 
do not know about built-in types :P

There are few ways to fix it, sorted from the smallest impact on a user code 
base to a-bomb size:
- Add conversion QDateTime -> QTime (Up to now only Olivier agreed with me 
that it is ok to add a new conversions)
- If two QVaraints are not equal we can check if swapping left and right sides 
helps. Inefficient, another behavior change and as odd as the current behavior. 
Nothing to gain really.
- Always compare QVariants twice left to right and right to left. Terribly 
inefficient, more sensible output. Big behavior change as most of comparison 
would return false.
- Allow comparisons of the same types or if there is explicitly registered 
comparisons otherwise return false. Completely different behavior then the 
current one.
- Do not allow QVariant comparison, we can not support custom types if they do 
not register conversion anyway so why bother.

Cheers,
  Jędrek



More information about the Development mailing list