QMetaType::Float not in QVariant::Type

QMetaType::Float not in QVariant::Type

本文关键字:QVariant Type in not Float QMetaType      更新时间:2023-10-16

我有一个工作良好的应用程序,但它没有编译与警告打开。我试着把它打开,把它们整理出来,但对如何解决这个问题已经没有想法了。我有:

QVariant someVar     
QVariant::Type variantType = someVar.type();
switch (variantType) {
    case QMetaType::QString:
        doSomething1();
        break;
    case QMetaType::Float:
        doSomething2();
        break;
}

并得到这个警告/错误:

error: case value ‘135’ not in enumerated type ‘QVariant::Type’ [-Werror=switch]

中的QMetaType::Float行。我检查了QT文档,它列出了QMetaType::Float值38。是什么导致了这一切?

我能找到的最接近的东西是在https://github.com/qbittorrent/qBittorrent/issues/2510有相同的错误。有人遇到过这个吗?

Qt在这两个枚举(QMetaType::TypeQVariant::Type)上玩了一些肮脏的把戏。引用4.8.4 docs on QVariant::type():

返回存储在变量中的值的存储类型。虽然这个函数被声明为返回QVariant::Type,但是返回值应该被解释为QMetaType::Type。特别地,只有当值等于或大于QMetaType::User时,才返回QVariant::UserType

请注意,QVariant::Char ~ QVariant::RegExpQVariant::Font ~ QVariant::Transform的返回值与QMetaType::QChar ~ QMetaType::QRegExpQMetaType::QFont ~ QMetaType::QQuaternion的返回值相对应。

还要注意,void*longshortunsigned longunsigned shortunsigned charfloatQObject*QWidget*类型在QMetaType::Type中表示,而在QVariant::Type中没有,它们可以通过这个函数返回。但是,在针对QVariant::Type进行测试时,它们被认为是用户定义的类型。

换句话说,函数QVariant::type()返回类型为QVariant::TypeQMetaType::Type的值,并且这两个枚举共享很多(但不是全部)枚举数。这使得在严格的类型系统中处理它们变得困难——它们基本上是一种摇摆不定的类型。

在您的示例中,请注意,枚举数QMetaType::Float而不是QVariant::Type中有直接等效的枚举数之一。

我想说,沉默警告的最好方法是将variantType更改为QMetaType::Type,可能会对初始化进行强制转换和/或必要时引用Qt文档的注释。

只需打开QMetaType::Type。这样做是有效的,因为尽管返回类型是QVariant::Type,但QVariant::type()的含义是QMetaType::Type的含义。这是一个API的怪癖/bug,你必须解决:

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

这个怪癖的原因完全是历史性的。QVariant::type()返回一个"错误"类型,只是为了在Qt 5系列中保持二进制兼容性。在Qt 6中,IIRC中的QVariant::Type只是QMetaType::Type的别名(可能也是一个已弃用的别名)。

QVariant::Type不包含名为Float的条目(参见qvariant.h)