c++qtqmetaobject

Is there a way to use QMetaEnum with Q_ENUMS belonging to non Q_OBJECT or Q_GADGET class?


For example I have the following class:

namespace someName
{
    class someClass
    {
        Q_ENUMS(ESomeEnum)

        public:
        enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};

        // ... some other things ..
    }
}

Q_DECLARE_METATYPE(someName::someClass)

Is there a way to use QMetaEnum::valueToKey or QMetaEnum::keyToValue ?

Tried the method in this answer but got the following error:

error: static assertion failed: QMetaEnum::fromType only works with enums declared as Q_ENUM or Q_FLAG
#define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)

I can employ X-Macros to get my desired output but it would also be nice to learn more tricks in Qt.


Solution

  • No, there isn't, because Q_ENUM's functionality is implemented in code generated by moc, and moc ignores classes that are neither Q_OBJECT nor Q_GADGET. There's no reason for not using a Q_GADGET since it has no effect on object size: adds no virtual methods nor data fields.

    The following demonstrates this:

    #include <QtCore>
    
    namespace Ns {
    class Class {
       Q_GADGET
    public:
       enum ESomeEnum {ENUM_A, ENUM_B, ENUM_C};
       Q_ENUM(ESomeEnum)
    };
    }
    
    int main() {
       auto metaEnum = QMetaEnum::fromType<Ns::Class::ESomeEnum>();
       qDebug() << sizeof(Ns::Class) << metaEnum.valueToKey(Ns::Class::ENUM_A);
    }
    #include "main.moc"
    

    Output:

    1 ENUM_A
    

    On this particular platform (and many others), empty classes are of size 1.