代码之家  ›  专栏  ›  技术社区  ›  Krupip

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

  •  2
  • Krupip  · 技术社区  · 7 年前

    我正在注册 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()声明,编译将失败。

    在谷歌上搜索后,我发现 this correspondence ,因为谷歌没有缓存结果,所以只能通过第三方存档网站获取:

    通过***@fastmail发布。fm Thiago——qMetaTypeId文档 ( http://qt-project.org/doc/qt-5.1/qtcore/qmetatype.html#qMetaTypeId ) 特别声明使用此函数的类型注册是 在编译时解析,而不是在运行时解析。

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

    然而,这是5年前做的,我怀疑文档在那时候不会被更正或被证明是正确的!

    为了在其他系统中使用QVariant,这似乎是一个相当常见的问题,如果在这种情况下我能做些什么来正确使用QVariant呢?有什么方法可以在编译时获取ID吗?

    注意,我使用C++ 14与QT 5.8,如果我需要升级QT,但是我可以。

    编辑:

    我已经升级了我的mingw-64版本和我的QT版本,它仍然给出相同的错误。此外,我还尝试注册一个空白结构,如下所示:

    struct Test{
    };
    Q_DECLARE_METATYPE (Test)
    
    
    const int test_enum= qMetaTypeId<Test>();
    

    0 回复  |  直到 7 年前