Reputation: 4892
I'm trying to register std::string
for use with QVariant, and have it convert to another type which also functions as a variant, but is needed for serialization. I tried to do this with the following code:
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;
}
}
but was met with the following error:
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(); }
If I declare it instead constant expression:
constexpr int std_string_enum = qMetaTypeId<std::string>();
I get the following error:
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(); }
I'm confused by this error, as the documentation states (emphasis mine):
Returns the meta type id of type T at compile time. If the type was not declared with Q_DECLARE_METATYPE(), compilation will fail.
After googling this, I found this correspondence, which was only available through a third party archival site as google hadn't cached the results:
Post by a***@fastmail.fm Thiago - The qMetaTypeId documentation (http://qt-project.org/doc/qt-5.1/qtcore/qmetatype.html#qMetaTypeId) specifically states that the type registration using this function is resolved at compile-time, not run-time.
The documentation is wrong. What Stephen said is correct.
however this was made 5 years ago, and I'm skeptical that the documentation wouldn't have been corrected or been proven correct in that time!
This seems like a fairly common problem in order to use qvariants with other systems, what if anything can I do to properly use QVariant in this scenario? Is there some way I can get the ID at compile time?
Note I'm using C++ 14 with Qt 5.8, if I need to upgrade qt however I can.
EDIT:
I've upgraded my mingw-64 version and my QT version, it still gives the same error. Additionally I've tried just registering a blank struct like so:
struct Test{
};
Q_DECLARE_METATYPE (Test)
const int test_enum= qMetaTypeId<Test>();
and it doesn't work
Upvotes: 2
Views: 1044