[Development] QFlags Zero handling
Olivier Goffart
olivier at woboq.com
Sat Jan 21 17:10:04 CET 2017
On Samstag, 21. Januar 2017 11:30:40 CET Stephen Kelly wrote:
> Hi,
>
> Does anyone know why QFlags has a constructor taking a Zero pointer? My
> guess is that it's a hack to make initializing like
>
> Qt::WindowFlags = 0
>
> work?
Correct.
We want to be able to initialize it with the literal 0, but not with any int
or unrelated enum value:
Qt::WindowFlags foo = 0; // should work
Qt::WindowFlags bar = 42; // should NOT work
Qt::WindowFlags bar = Qt::DownArrow; // MUST NOT work (unrelated enum)
So the trick is to allow the initialization with a pointer so we can use 0,
but not anything that gets converted to an int.
A QFlags(int) constructor would work with any enum or anything that can be
converted to int. That would defeat the purpose of QFlags.
> The problem encountered is that porting tools convert that to
>
> Qt::WindowFlags = nullptr
>
> which is undesirable.
Yes, this is a case in which 0 was desired over nullptr. The problem is that
you now even get a warning if you use "= 0" with some warning options.
So the trick is not really working anymore.
I'm not aware of another trick to enable the implicit conversion from '0' and
no other thing.
If we allow implicit conversion from int, but still want to disable conversion
from other enums, we could come up to something like this:
QFlags(T); // normal constructor for the enum type
QFlags(int); // allow conversion from int
// disallow construction from all other enumerations
template<typename X>
QFlags(X, std::enable_if_t<std::is_enum_v<X>> *= nullptr) = delete;
But I'd rather QFlags not being implicitly constructed from int.
> https://mail.kde.org/pipermail/kde-frameworks-devel/2017-January/042091.html
>
> Is there a better solution to that with modern c++?
As mentioned in the link, if you don't want to use nullptr because it's not
pretty, and you don't want to use 0 because of the warning. Then the remaining
option is to force the default constructor:
Qt::WindowFlags = {};
> PS:
>
> I mentioned there that Q_NO_TYPESAFE_FLAGS is broken. [...]
> The define could be removed from qflags.h. Perhaps something could be
> changed in qnamespace.h to allow the code to compile instead (and make the
> enum meta objects not available), but it doesn't seem worth it.
Yes, Q_NO_TYPESAFE_FLAGS is broken, as are most of the Q_NO_XXX.
I guess it could be removed, since QFlags does not have runtime cost, there is
no point of keeping it, even for qt lite.
--
Olivier
Woboq - Qt services and support - https://woboq.com - https://code.woboq.org
More information about the Development
mailing list