[Development] QOptional
Marc Mutz
marc.mutz at kdab.com
Wed Aug 20 20:49:03 CEST 2014
On Wednesday 20 August 2014 20:04:24 Иван Комиссаров wrote:
> First is a QVariant integration. I think, i should add:
> 1) template<typename T> QVariant::QVariant(const QOptional<T> &o);
> constructor
static fromOptionalValue()
(like fromValue())
Please don't add a templated ctor to QVariant. It currently doesn't have one,
and if you add that ctor, as implicit even, you may change the meaning of this
code:
QVariant v(t);
where t, say, has an implicit conversion to int. The call might become
ambiguous.
Also, QVariant v = t; for any currently supported type decltype(t) means that
v _contains_ a t. In particular, if QVariant v = t compiles, then it is equal
(in type and content) to fromValue(t). With your proposal that's no longer
true. If t is a QOptional<T>, v would now contain a T, which is different from
decltype(t).
> 2) template<typename T> QOptional<T> QVariant::toOptional()
> const; method (like value<T>())
toOptional_Value_() (to mimick value<T>().
> Right now, QOptional has isNull() method that indicates that optional
> object has no value. I suggest to rename this method to isValid() and add
> new isNull() method that checks if optional contains default-constructed
> value. This will make it more consistent with QVariant API.
What QOptional should be consistent with is a T*, and std::optional, because
that's what it's replacing. Qt smart pointers have isNull(). Just mention the
simile in the docs, and no-one will look for isNull(). IIRC, std::optional
uses something way more esoteric, like is_engaged() or so (I'm not proposing
that).
With isValid() you will have the same problem. If isNull() checks !opt ||
opt.value().isNull(), then it's hard to argue why isValid() shouĺd check
anything but opt && opt.value().isValid().
I don't find the QVariant::isNull behaviour any useful or intuitive. It's too
smart. You can always use v.value<T>().isNull() because value() will return a
default-constructed T if invalid.
> So, the i vote for following behaviour;
> Invalid QVariant (no type) <-> invalid QOptional of type T
> null QVariant (QString) <-> valid QOptional containing QString()
> non-null QVariant containig QString("") <-> valid QOptional containing
> QString("") non-null QVariant containing non-empty string <-> valid
> QOptional containing non-empty string
>
> Second, i would like to hear some expertise about current implementation
> using "aligned" storage. Will it work? More, this implementation has a
> problem - QOptional(T) constructor can't be marked constexpr (as it uses
> placement new), which makes class useless for constant expressions at all.
> Should i add also c++11 implementation based on unions?
In C++11 generalized unions you still have to use placement new to intialize
non-POD members, iirc.
While it would be nice if the QOptional(T) ctor would be constexpr, I don't
think that's a strong requirement. QOptional() and many other
> (what would happen
> if we use c++98 compiled Qt with c++11 compiled app?)
As long as the struct are layout-compatible, probably nothing. I don't know of
the top of my head, however, whether C++ defines the memory layout of unions
with members of different size, though the only sane definition would be that
all members have the same address.
Thanks,
Marc
--
Qt Developer Days 2014 - October 6 - 8 at BCC, Berlin
Marc Mutz <marc.mutz at kdab.com> | Senior Software Engineer
KDAB (Deutschland) GmbH & Co.KG, a KDAB Group Company
www.kdab.com || Germany +49-30-521325470 || Sweden (HQ) +46-563-540090
KDAB - Qt Experts - Platform-Independent Software Solutions
More information about the Development
mailing list