On Tuesday 15 July 2014 08:55:29 Jędrzej Nowacki wrote: > Hi, > > I would like to discuss type conversions in Qt. As you may know, Qt has > the ability to convert a known type to another known type. This works for > trivial cases like, for example, "int" to "long", but also for more complex > ones like "QByteArray" to "QString" or "CustomType" to "OtherCustomType". > Type conversion in Qt happens mostly without user interaction, for example > in QObject introspection or in QML, but it also can be used through public > API: - QVariant::convert -> converts wrapped value to target type > - QVariant::canConvert -> fast check if it may be possible to convert > wrapped type to a given target, which is, in my opinion, pretty useless, > unless the real conversion is really heavy > - QMetaType::registerConverter -> allows to register a custom converter > function for a user defined type > - QMetaType::convert -> perform conversion between two types > > I would like to agree on some rules, regarding conversions, as the > current approach is chaotic: > > 1. Are we allowed to add new conversions? > > The question is tricky because adding a new conversion is a behavior > change, as this code: > if (variant.canConvert(QMetaType::int)) ... > may work differently. If we add custom types into the mix, everything > is even more complex.
I'd say yes, for sensible conversion You are right that it is a behaviour change, but i think it is worth changing it. > 1.1 Patch release or minor release only? [...] Minor release only of course. Path release is only for regressions and critical fixes. New conversions is a feature. > 1.2 Should conversion be perfect or based on a best effort? > > Some of the conversion API returns a "bool" value which is a status > of conversion. What should it return if a conversion is not perfect, for > example "int(-1) -> uint" or "QVariantList{string, int, myobject} -> > QStringList", should such a case be detected? How do we define the perfect > conversion? Sometimes only ideal, data lossless, conversions should be > allowed, for example QtTestLib is quite strict about it and it allows only > safe conversions. So, for example, "int -> long" but not "uint -> int", but > I guess for normal use cases such strictness is not necessary. > I think we should base conversions on the best effort and set the > status to false only if a conversion failed completely, that is mainly if a > conversion is unknown or if underlying implementation detected a failure, > like "QByteArray -> float" which uses QByteArray::toFloat(bool *ok) You have to think of the use cases for QVariant::convert. Most common are things like QVariant::toString and QVariant::toInt and such. You usually have a function that expect a string or an int, and you do best effort to get that from the QVariant to ease programmer life in the wonderful wold of dynamic typing :-) It is true that it would be good to have a bool *ok in case the conversion failed totally. > 1.3 Should we try to support a user's type conversions out of the box? > > Currently a user needs to manually register a conversion function > so Qt can know it and use it. For certain types we can do much better, > because we can automatically convert some types. For example: > QVector<char> -> QLinkedList<int> > QList<Foo> -> QVector<Foo> > QPointer<Foo> -> QObject* > QPointer<Foo> -> void* > QSharedDataPointer<Foo> -> bool > MyQObject* -> QPointer<MyQObject> > Currently we are not doing it for one reason which is behavior > compatibility. What if a user already defined a conversion that we want to > add? It could happen because the conversion was not available in a previous > Qt version. The problem is that the new conversion function may behave in a > different way, especially in edge cases and because of the lack of > perfection mentioned in 1.2. We need to pick only one function. That could > be the Qt version, but then we risk that an existing code will not work > anymore. Are we willing to accept that? > I believe that we should document the problem, and allow the > conversions. I think we could try to automatically do conversion when we know how to do it. And if there is an user defined conversion, it overrides the automatic one. > 1.4 Should a user be able to add Qt types conversion on his own? > > Some conversions are missing, some we consider as not safe. A user, > assuming that he knows what he is doing, could register a conversion; for > example, "QString -> QChar", how bad is it? Currently, such usage is > blocked, because we are afraid that in the future we may add a conversion > that overrides it. > In my opinion it is not needed; it is a corner case, because we a) > should have the conversion and then it will appear in a future version b) > the conversion is invalid, and it is a sign of a user's broken code. I'd say no. > 2. Can we modify an existing conversion? > > All modification changes behavior. Of course we assume that changes are > sensible, but still it may break existing code. > 2.1 Can we improve a conversion? > > For example, "QStringList -> QString" is very tempting, as it works > only if the list is of size 1. The conversion could join all strings > instead, it would be almost backward compatible, as we would alter only > conversions that failed previously. > I believe we should allow that; I can not wait for the > bike-shedding about which character or string we should use to join them. I'd say yes. > > 2.2 How much we can break? > > Is missing data in the result of a conversion a reasonable cause to > break behavior? For example "QVariant(QColor) -> QString" doesn't include > the alpha channel (QTBUG-37851). That should be fixed. > As I said in 1.2, I think that we should take the approach of the > best effort and nobody should depend on the exact result of a conversion. We > should reserve our right to improve it, so the best effort is not a lie. Yes > 2.3 How to decide if a conversion should be improved? > > A conversion may be arbitrary. For example, most of the conversions > to QString. Should "bool(false) -> QString" return "False", "0", "false"? > What about precision of, for example, "double -> QString" ? We use common sense on a case by case basic. > 3. Can we remove existing conversions? > > I would say, no, but maybe in a major release. Probably not. -- Olivier Woboq - Qt services and support - http://woboq.com - http://code.woboq.org _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development