[Development] Use QMetaEnum::keyCount() to initialise array
Tom Isaacson
Tom.Isaacson at navico.com
Sun Dec 30 20:43:21 CET 2018
Is it possible to use QMetaEnum::keyCount() to initialise an array? Something like:
const QMetaEnum metaEnum = QMetaEnum::fromType<MyArray>();
int MyArray[metaEnum.keyCount()];
After asking this on the Qt-Interest forum I spent a bit of time investigating. Q_ENUM declares functions with Q_DECL_CONSTEXPR:
#define Q_ENUM(ENUM) \
friend Q_DECL_CONSTEXPR const QMetaObject *qt_getEnumMetaObject(ENUM) Q_DECL_NOEXCEPT { return &staticMetaObject; } \
friend Q_DECL_CONSTEXPR const char *qt_getEnumName(ENUM) Q_DECL_NOEXCEPT { return #ENUM; }
In my example code above, QMetaEnum::fromType() calls these functions:
template<typename T> static QMetaEnum fromType() {
Q_STATIC_ASSERT_X(QtPrivate::IsQEnumHelper<T>::Value,
"QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG");
const QMetaObject *metaObject = qt_getEnumMetaObject(T());
const char *name = qt_getEnumName(T());
return metaObject->enumerator(metaObject->indexOfEnumerator(name));
}
Where it breaks is the last line, because QMetaObject::indexOfEnumerator() uses d.data:
https://github.com/qt/qtbase/blob/96efc38f100686a8183f45367e54bf6cb670bdba/src/corelib/kernel/qmetaobject.cpp#L968
int QMetaObject::indexOfEnumerator(const char *name) const
{
const QMetaObject *m = this;
while (m) {
const QMetaObjectPrivate *d = priv(m->d.data);
Which is only defined as const:
https://github.com/qt/qtbase/blob/96efc38f100686a8183f45367e54bf6cb670bdba/src/corelib/kernel/qobjectdefs.h#L578
struct { // private data
const QMetaObject *superdata;
const QByteArrayData *stringdata;
const uint *data;
I don't know how the Meta-Object Compiler creates this but surely it's possible to change it to be constexpr?
Tom Isaacson
More information about the Development
mailing list