QMetaType :: Float不在QVariant :: Type中

时间:2015-07-08 10:55:28

标签: c++ qt

我有一个正常运行的应用程序,但没有打开警告编译。我正在尝试将其重新打开并对其进行整理,但是如何解决这个问题的想法已经用完了。我有:

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,它有同样的错误。有没有人遇到过这个?

3 个答案:

答案 0 :(得分:5)

Qt在这两个枚举(QMetaType::TypeQVariant::Type)中扮演一些肮脏的伎俩。引用QVariant::type()上的4.8.4文档:

  

返回变体中存储的值的存储类型。虽然此函数声明为返回QVariant::Type,但返回值应解释为QMetaType::Type。特别是,仅当值等于或大于QVariant::UserType时才会返回QMetaType::User

     

请注意,QVariant::CharQVariant::RegExp以及QVariant::FontQVariant::Transform范围内的返回值对应于QMetaType::QChar到{{1}范围内的值}和QMetaType::QRegExpQMetaType::QFont

     

另请注意,QMetaType::QQuaternionvoid*longshortunsigned longunsigned shortunsigned char类型, floatQObject*QWidget*中表示,但不在QMetaType::Type中,并且此函数可以返回它们。但是,在针对QVariant::Type进行测试时,它们被视为用户定义的类型。

换句话说,函数QVariant::Type返回QVariant::type()类型为QMetaType::Type的值,这两个枚举共享很多(但不是全部)枚举器。这使得在严格的类型系统中处理它们变得困难 - 它们基本上是令人颤抖的,不稳定的类型化的东西。

在您的情况下,请注意枚举器QVariant::Type属于那些QMetaType::Float中具有直接等效词的​​人。

我想说停止警告的最佳方法是将QVariant::Type更改为variantType,可能会在初始化时使用强制转换和/或在必要时引用Qt文档。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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