[Interest] Is it safe to call qRegisterMetaType() before main()?

Nikos Chantziaras realnc at gmail.com
Mon Jul 29 22:28:04 CEST 2019


On 28/07/2019 07:15, Thiago Macieira wrote:
> On Friday, 26 July 2019 17:35:03 PDT Nikos Chantziaras wrote:
>> I didn't (although I use Q_ENUM, but it does the same job.) But there's
>> no constructor to put qRegisterMetaType() in. It's an enum. There's no
>> constructor. Some enums are in a namespace, some are in a class, but
>> even with an enum that is in a class, users of can just use the enum in
>> their own signals/slots prior to instantiating the class that declares
>> the enum. It will stay unregistered until the first instance of the
>> class is created.
>> ____________________
> 
> I meant in the class it's most likely to be used in.

Well, putting it in the class it's most likely to be used in is not good 
enough, because this results in "it most likely has been registered, but 
maybe not." To be sure it's registered, you'd have to register it in 
*every* class it's used in. What if you forget? It doesn't scale. Too 
error prone. It's much (much!) better to be in a situation where only 
two cases are possible: it's either *always* registered, or it's *never* 
registered. There should be no middle-ground.

In case of enums, if the enum is in "globals.h", then "globals.cpp" 
should be responsible for registering it. Since global initializers can 
be removed by the linker as they're not referenced in the executable, 
then I'll just have to provide initialization functions and call them in 
main(). That way the qRegisterMetatype() calls stay within the source 
file of the "owner" of the type, and forgetting to register newly added 
types is less likely.


> This is only required when referring to it by name, such as in old-style
> signal-slot connection, QML, D-Bus, etc.

They're new-style connections, but are sometimes of QueuedConnection 
type since some connections are used for inter-thread communication. If 
I don't use Q_ENUM or Q_REGISTER_METATYPE (and thus also don't call 
qRegisterMetatype(),) the connections won't work and you get this at 
runtime:

   QObject::connect: Cannot queue arguments of type 'MyClass::MyEnum'


> Loading it into a QVariant automatically registers, as QVariant calls
> qMetaTypeId<Enum>() to get the metatype ID.

Not sure what you mean here. I'm not using a QVariant anywhere, at least 
not explicitly.



More information about the Interest mailing list