我正在注册
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>();