[Development] std::optional for Q_PROPERTY
Giuseppe D'Angelo
giuseppe.dangelo at kdab.com
Fri Jul 21 11:35:56 CEST 2023
On 21/07/2023 11:01, Volker Hilsheimer via Development wrote:
> How about conversion:
I, for one, would like to stop seeing magic conversions added into
QVariant, and keep breaking stuff at every Qt major release because we
realize we went overboard and have to remove features.
Now, one could think of folding QVariant and std::optional nullability
semantics, but this becomes hairy very very quick. Take this:
std::optional<int> opt; // nullopt
QVariant v = QVariant::fromValue(opt);
Is `v` a null QVariant with Int metatype, or a valid variant with a
std::optional<int> metatype loaded with a copy of the optional? What if
`opt` is loaded instead?
Bonus question: this works *today*, and guess what it does?
So this at a minimum is a different named constructor:
QVariant::fromStdOptional or similar. This doesn't help at all in
generic code (e.g. in the property system) -- when is one supposed to
unwrap an optional vs keep it wrapped?
> QVariant(std::optional<T>>).value<U>(); // return U{} if T cannot be converted; otherwise U(T);
This isn't how QVariant works today for
`QVariant::fromValue(T{}).value<U>()`, unless T and U are a specific
combination of types in a whitelist of sorts, or have a custom
conversion registered; so, if anything, it should follow the same
semantics: refuse the conversion, unless it's special or registered. And
by "registered" I mean registered from `std::optional<T>` to `U`, not
from `T` to `U`.
> 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?
All of these already have established semantics. We can't change them
without breaking API. We need an `optionalValue<T>()` accessor or
something like that (again, that kills the idea of using this in generic
code, properties, etc.).
> QVariant().value<std::optional<T>>();
Returns default-constructed std::optional<T> (i.e. nullopt)
> QVariant(42).value<std::optional<int>>(); // std::optional holding 42
No, returns nullopt, types don't match and not in the list of magical
conversions (and we can't extend such a list because it's an API break)
> QVariant(QSize()).value<std::optional<int>>();
Nullopt again (types don't match).
My 2 c,
--
Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4244 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.qt-project.org/pipermail/development/attachments/20230721/0e6d6734/attachment.bin>
More information about the Development
mailing list