[Development] Converting types in Qt

Ziller Eike Eike.Ziller at digia.com
Thu Jul 17 15:14:16 CEST 2014

On Jul 17, 2014, at 1:28 PM, Jędrzej Nowacki <jedrzej.nowacki at digia.com> 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. My recommendation is to not use the 
> comparison at all. If you want more "features" of QVariant you can look into 
> isNull() this is a perfect randomizer :P.

> The whole discussion took wrong 
> direction. I didn't want to discuss QVariant API, which is not fixable, even 
> Qt6 would not help, to much staff depends on it. 

Well, the discussion is still sort of the same (and sort of not). The original question was, if we can/should add new type conversions, and/or which kind of conversions these could be. I think the investigations here about the API and workings of QVariant give some hints on what an answer to that might be.
There is no need to expose the brokenness of the API even more by adding conversions that trigger it.

operator== would be less bad if there were only symmetric and lossless conversions, so do not introduce any additional lossy or asymmetric conversions.
Also, the uses of QVariant::toString (&fromString), that we have found in Qt Creator ((de)serialization of QVariantMaps), definitely break if this conversion is *not* lossless (or not symmetric).

"int <-> long” kind of conversions might be sort of ok-ish, since the actual conversion can still fail if the long doesn’t fit into int, i.e. for values that actually fit into both types the conversion is lossless, for values that do not fit into both types, the conversion fails in one direction, and is not possible to start with in the other direction.
Since this can only be found out during runtime, I’d try to avoid that though, and definitely not put that into the extreme.

I would avoid conversions between containers that do not have the exact same type. "QLinkedList<T>  <=>  QVector<T>” maybe, “QLinkedList<int>  <=>  QVector<long>” ... no.

Do not add conversions that do not have a “canonical way” to do it, and which do not have a corresponding toXXX function without parameters in the corresponding types.
The exception to the “canonical way" rule *might* be toString/fromString conversions, because of its usefulness. There is no canonical way to convert bool <-> string, but it might be useful for things like (de)serialization. (I’m not very convinced of toString conversion being very useful in the MVC context, actually, except maybe for quick-hack-debugging. For production you should be in better control of what you show to your user. I’m only half-convinced about its usefulness for (de)serialization.) Taking QString out of the rule has the disadvantage that it makes it harder if you actually want to hold string “data” in your variant (for which you would want saner conversion rules).

Br, Eike

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