[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