Qt - Q_DECLARE_METATYPE() with an enum class type

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);

You can use Q_ENUM which was added in Qt 5.5:

enum class Bar
{
    X,
    Y,
    Z
};
Q_ENUM(Bar)

QVariant var = QVariant::fromValue(Bar::X);

Tags:

C++

Qt

Enum Class