On Thu, Jul 17, 2014 at 02:38:40PM +0200, Jędrzej Nowacki 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.
The broad problem here is _too many_ conversions. In this case specifically the QDate-to-QDateTime conversion. > 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: It does not have to remain broken. The only reason to not fix it right now are compatibility promises. A trivial solution (and one of the few correct ones) is to consider QVariants as equal if and only if they have identical type and their typed values are the same, according to a (proper) equivalence relation set up for this type. Of course one can come up with more elaborate schemes to set up equivalency classes like putting all integral type into one bucket. Some might even make sense. What won't work are chains of conversions int - QChar - QString - QStringList without a direct conversion from int to QStringList. > 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) Not acceptable. This loses precision, and consequently can't be made transitive, i.e. there will be objects a, b, and c such that a == b, b == c, with a != c. > - 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. Not acceptable. Albeit ths would solve the symmetry problem, the transitivity problem remains. > - 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. Not acceptable. The ransitivity problem remains. We are looking in the right direction, though: Things are less often equal than it appears to be "convienient". > - Allow comparisons of the same types or if there is explicitly registered > comparisons otherwise return false. Completely different behavior then the > current one. [*] Acceptable for Qt 6 (and for Qt 5 as opt-in, due to the changed behaviour) if and only if the "explicitly registered comparison functions" don't violate any of the symmetricy/transitive/reflexive requirements. > - Do not allow QVariant comparison, we can not support custom types if they > do > not register conversion anyway so why bother. Acceptable for Qt 6 (and for Qt 5 as opt-in, due to the changed behaviour), but overshooting. QVariants of the same type with usable comparison for that type are perfectly comparable. The solution is [*]. Andre' _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development