c++qtenum-class

Qt - Q_DECLARE_METATYPE() with an enum class type


Is there a way to use Q_DECLARE_METATYPE() with enum class types? I know old enums work but what about these new, strongly typed, ones? Can't find anything regarding this problem elsewhere. I'm using the latest Qt version available.

Example:

enum Foo
{
    A,
    B,
    C
};

Q_DECLARE_METATYPE(Foo)
QVariant var = Foo::A; // works fine

enum class Bar
{
    X,
    Y,
    Z
};

Q_DECLARE_METATYPE(Bar)
QVariant var = Bar::X; // doesn't compile

Solution

  • This is because when you use a plain old enum:

    enum Foo { A, B, C };
    QVariant var = Foo::A;
    

    the compiler in fact uses the following constructor to build up your var instance:

    QVariant(const QVariant& other);
    

    And going further, the other instance is created using the following non-explicit constructor:

    QVariant(int val);
    

    This is possible, because old enums can be treated as integral values.

    To sum up, this is what the compiler sees and does behind the scene:

    int temp = Foo::A;
    QVariant var = QVariant(temp);
    

    As you know, enum classes CAN NOT be treated as integral values without an explicit cast. Thus, the compiler cannot implicitly convert your type to int, and invoke a matching constructor (to be precise: the best candidate from all available constructors). That is, there is a predefined set of constructors QVariant offers. You cannot add a new one using Q_DECLARE_METATYPE macro.

    To use QVariant with your own type, you should rather use QVariant::fromValue(const T& t) function:

    enum class Foo { A, B, C };
    QVariant var = QVariant::fromValue(Foo::A);
    

    or alternatively:

    enum class Foo { A, B, C };
    QVariant var;
    var.setValue(Foo::A);