How about conversion:

     QVariant(std::optional<T>>).value<U>(); // return U{} if T cannot be 
converted; otherwise U(T);

     QVariant().value<std::optional<T>>(); // nullopt, not a std::optional 
holding a T{}
     QVariant(42).value<std::optional<int>>(); // std::optional holding 42
     QVariant(QSize()).value<std::optional<int>>(); // probably nullopt?

QML checks the metatype before doing anything interesting with an unknown piece of QVariant. If it knows it's an optional (after some teaching it), it would also know how to retrieve the T value. Nullopt should indeed be mapped to void in QML and undefined in JS.

QVariant is not the best way to encode an optional<T>. Since QML would have to know about it's meaning anyway, we should use the otpional<T> itself as the value passed to/from getter and setter. We wouldn't need any special hackery in QVariant and/or moc for that.

If we make QML understand "optional" as a native concept the same way it understands "list", we generally add type registration overhead. I was already somewhat unwilling to do that for lists but I didn't come up with anything better back then. Each QML type now has a list "companion type" with a separate entry in the type registry. This is mostly because QMetaType doesn't tell us anything about list types. We need to store the information about the type being a list and what elements it can hold (and the default list type for a given element type) separately. The same thing will eventually happen for map<T> and at latest if we add variant<T, U, V ...> it's going to disintegrate. So, what we actually need is a better QML type registry and richer information from QMetaType.

It looks like we're going to discuss this at QtCS.

best regards,
Ulf
--
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development

Reply via email to