[Interest] Q_DECLARE_SMART_POINTER_METATYPE type restriction

Giuseppe D'Angelo giuseppe.dangelo at kdab.com
Wed Jan 29 00:36:13 CET 2020

Il 28/01/20 21:59, joel at embedded.pro ha scritto:
> I was investigating the idea of storing an std::shared_ptr<T> in a 
> QVariant. This would allow me to put a shared pointer to my custom data 
> int a QComboBox's data field.
> I'm aware of the existence of QSharedPointer. The data I am working with 
> is only available wrapped into an std::shared_ptr (data provided by a 
> 3rd party component). This leaves me with the choice of either storing 
> raw pointers or registering my own type for the use with QVariant.
> For this, I've been looking at Q_DECLARE_SMART_POINTER_METATYPE. The 
> documentation has the following to say about this macro:
>>>  This macro makes the smart pointer SmartPointer known to QMetaType as 
> a smart pointer. This makes it possible to put an instance of 
> SmartPointer<T> into a QVariant, if T is a type which inherits QObject.
> I'd be interested to know why T would be restricted to a type which 
> inherits QObject.
> Can anybody enlighten me?

If you have a concrete type, like std::shared_pt<Foo>, then just 
Q_DECLARE_METATYPE(std::shared_ptr<Foo>) is sufficient and necessary for 
storing it into a QVariant. Then you can set it as your combobox' user 
data or whatever.

If you want to register a _class template_ so that any instantiation of 
your template with a type T that inherits QObject is automatically 
registered, then you have Q_DECLARE_SMART_POINTER_METATYPE. The reason 
for this has mostly to do with QVariant's ability of unwrapping the 
smart pointer and apply qobject_cast to it, e.g.

template <typename T> class MySmartPtr { ~~~ };

MySmartPtr<QWidget> ptr = new QPushButton;
QVariant v(ptr); // works
v.canConvert<QObject *>(); // true
QObject *rawPtr = v.value<QObject *>(); // works
QAbstractButton *downCast = v.value<QAbstractButton *>(); // works too

To say it all:

1) this ability of QVariant of doing magic casts is somewhat frowned upon;
2) Q_DECLARE_SMART_POINTER_METATYPE for all std:: smart pointers should 
really something that Qt itself takes care of (it's not at the moment, I 
can only guess we don't want a central header like qmetatype.h to pull 
in <memory>).


Giuseppe D'Angelo | giuseppe.dangelo at kdab.com | Senior Software Engineer
KDAB (France) S.A.S., a KDAB Group company
Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com
KDAB - The Qt, C++ and OpenGL Experts

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4329 bytes
Desc: Firma crittografica S/MIME
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20200129/0210d182/attachment.bin>

More information about the Interest mailing list