[Development] Converting types in Qt

Ziller Eike Eike.Ziller at digia.com
Thu Jul 17 15:07:26 CEST 2014


On Jul 17, 2014, at 2:38 PM, Jędrzej Nowacki <jedrzej.nowacki at digia.com> wrote:

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

Actually, adding a conversion QTime -> QDateTime wouldn’t help, because that conversion cannot “invent” the correct missing date information.
So, QVariant(dateTime) == QVariant(time) would still fail, because the date of the datetime that is created when converting time->datetime will not be the same as the original datetime.
In the presence of lossy conversions, you need to do conversions in both directions to make operator== symmetric.

> 
> 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
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development

-- 
Eike Ziller, Senior Software Engineer - Digia, Qt
 
Digia Germany GmbH, Rudower Chaussee 13, D-12489 Berlin
Geschäftsführer: Mika Pälsi, Juha Varelius, Tuula Haataja
Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 144331 B



More information about the Development mailing list