QMetaType::Float not in QVariant::Type

Qt plays somewhat dirty tricks witht these two enumerations (QMetaType::Type and QVariant::Type). Quoting 4.8.4 docs on QVariant::type():

Returns the storage type of the value stored in the variant. Although this function is declared as returning QVariant::Type, the return value should be interpreted as QMetaType::Type. In particular, QVariant::UserType is returned here only if the value is equal or greater than QMetaType::User.

Note that return values in the ranges QVariant::Char through QVariant::RegExp and QVariant::Font through QVariant::Transform correspond to the values in the ranges QMetaType::QChar through QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion.

Also note that the types void*, long, short, unsigned long, unsigned short, unsigned char, float, QObject*, and QWidget* are represented in QMetaType::Type but not in QVariant::Type, and they can be returned by this function. However, they are considered to be user defined types when tested against QVariant::Type.

In other words, the function QVariant::type() returns values of QMetaType::Type typed as QVariant::Type, and those two enumerations share a lot (but not all) of their enumerators. This makes dealing with them in a strict type system difficult—they're basically wibbly-wobbly typey-wypey stuff.

In your case, notice that the enumerator QMetaType::Float is among those which do not have a direct equivalent in QVariant::Type.

I would say that the best way to silence the warning would be to change variantType to QMetaType::Type, potentially with a cast on initialisation and/or a comment referring to Qt docs if necessary.


Simply switch on the QMetaType::Type. It is valid to do so, since the meaning of QVariant::type() is that of QMetaType::Type in spite of the return type being QVariant::Type. It's an API quirk/bug that you have to work around:

QVariant variant = ...;
switch (static_cast<QMetaType::Type>(variant.type())) {
  ...
}

The reason for the quirk is entirely historic. QVariant::type() returns a "wrong" type, only to retain binary compatibility within the Qt 5 series. In Qt 6, IIRC the QVariant::Type is just an alias for QMetaType::Type (and probably a deprecated one, too).

Tags:

C++

Qt