我正在尝试注册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,这只能通过第三方存档网站获得,因为谷歌没有缓存结果:
然而,这是在5年前制作的,而且我怀疑文档在那段时间内不会被纠正或被证明是正确的!发表于a***@fastmail.fm Thiago - qMetaTypeId文档 (http://qt-project.org/doc/qt-5.1/qtcore/qmetatype.html#qMetaTypeId) 具体说明使用此函数的类型注册是 在编译时解决,而不是在运行时解决。
文档错误。斯蒂芬说的是对的。
为了将qvariants与其他系统一起使用,这似乎是一个相当普遍的问题,如果有什么办法可以在这种情况下正确使用QVariant呢?有没有办法在编译时获取ID?
注意我正在使用Qt 5.8的C ++ 14,如果我需要升级qt,我可以。
编辑:
我升级了我的mingw-64版本和我的QT版本,它仍然会出现同样的错误。另外,我尝试过注册一个空白结构,如下所示:
struct Test{
};
Q_DECLARE_METATYPE (Test)
const int test_enum= qMetaTypeId<Test>();
它不起作用