在编译时获取声明的QMetaType的id?

时间:2018-05-21 14:41:16

标签: c++ qt variant compile-time compile-time-constant

我正在尝试注册std::string以便与QVariant一起使用,并将其转换为另一种类型,该类型也可用作变体,但需要进行序列化。我尝试使用以下代码执行此操作:

Q_DECLARE_METATYPE (std::string)


const int std_string_enum = qMetaTypeId<std::string>();


void to_example_type(example_type &j, const QVariant &q_variant) {
qRegisterMetaType<std::string>("std::string");
    switch (q_variant.userType()) {
        case QMetaType::Bool:
            j = q_variant.value<bool>();
            break;
        case QMetaType::Int:
            j = q_variant.value<int>();
            break;
        case QMetaType::UInt:
            j = q_variant.value<unsigned int>();
            break;
        case QMetaType::Double:
            j = q_variant.value<double>();
            break;
        case QMetaType::Long:
            j = q_variant.value<long>();
            break;
        case QMetaType::LongLong:
            j = q_variant.value<long long>();
            break;
        case QMetaType::Short:
            j = q_variant.value<short>();
            break;
        case QMetaType::Char:
            j = q_variant.value<char>();
            break;
        case QMetaType::ULong:
            j = q_variant.value<unsigned long>();
            break;
        case QMetaType::ULongLong:
            j = q_variant.value<unsigned long long>();
            break;
        case QMetaType::UShort:
            j = q_variant.value<unsigned short>();
            break;
        case QMetaType::UChar:
            j = q_variant.value<unsigned char>();
            break;
        case QMetaType::Float:
            j = q_variant.value<unsigned char>();
            break;
        case QMetaType::QString:
            j = (q_variant.value<QString>()).toStdString();
        case std_string_enum:
            j = q_variant.value<std::string>();
            break;
        default:
            assert((false, "Can't Convert to example_type"));
            break;
    }
}

但遇到以下错误:

error: the value of 'std_string_enum' is not usable in a constant expression

     case std_string_enum:

note: 'std_string_enum' was not initialized with a constant expression
 const int std_string_enum = qMetaTypeId<std::string>();

note: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' is not usable as a constexpr function because:
     static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }

如果我将其声明为常量表达式:

constexpr int std_string_enum = qMetaTypeId<std::string>();

我收到以下错误:

in constexpr expansion of 'qMetaTypeId<std::__cxx11::basic_string<char> >()'

error: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' called in a constant expression
     return QMetaTypeId2<T>::qt_metatype_id();

note: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' is not usable as a constexpr function because:
     static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }

error: call to non-constexpr function 'static int QMetaTypeId<std::__cxx11::basic_string<char> >::qt_metatype_id()'
 static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }

我对这个错误感到困惑,因为the documentation states(强调我的):

  

在编译时返回类型T的元类型ID。如果类型是   未使用Q_DECLARE_METATYPE()声明,编译将失败。

在Google上搜索之后,我找到了this correspondence,这只能通过第三方存档网站获得,因为谷歌没有缓存结果:

  
    

发表于a***@fastmail.fm Thiago - qMetaTypeId文档     (http://qt-project.org/doc/qt-5.1/qtcore/qmetatype.html#qMetaTypeId)     具体说明使用此函数的类型注册是     在编译时解决,而不是在运行时解决。

  
     

文档错误。斯蒂芬说的是对的。

然而,这是在5年前制作的,而且我怀疑文档在那段时间内不会被纠正或被证明是正确的!

为了将qvariants与其他系统一起使用,这似乎是一个相当普遍的问题,如果有什么办法可以在这种情况下正确使用QVariant呢?有没有办法在编译时获取ID?

注意我正在使用Qt 5.8的C ++ 14,如果我需要升级qt,我可以。

编辑:

我升级了我的mingw-64版本和我的QT版本,它仍然会出现同样的错误。另外,我尝试过注册一个空白结构,如下所示:

struct Test{
};
Q_DECLARE_METATYPE (Test)


const int test_enum= qMetaTypeId<Test>();

它不起作用

0 个答案:

没有答案