2

There's a similar question here that was looking for a workaround and a nice guide here which describes the meta-object system in Qt.But that doesn't explain directly why is it not possible to use a template class in the meta-object system.That's an annoying restriction.

Anyone know why ?

Parsa Mousavi
  • 1,052
  • 1
  • 13
  • 31
  • 1
    well probably is caused by what is generated by the macro, if every class has to have some unique Q_OBJECT id (example), different instantiation of the template will product different class with the same ID, since the macro is performed before the compiling, but this is just a thought since idk what the Q_OBJECT macro produce – Alberto Sinigaglia Jul 21 '20 at 18:30
  • This sounds like an xy problem. What are you trying to achieve that this particular restriction prohibits? – G.M. Jul 21 '20 at 18:41
  • @G.M. I want to write a helper class to run ```->setupUi``` of a desired form among the lots of ```.ui``` files.The problem is that the top-level class of those forms differ(e.g QDialog or QMainWindow) so I decided to use templates for that.If that helper class doesn't make use of signal and slot mechanism(**which is the case here**), then no problem.But I wondered why is there such a restriction at all? – Parsa Mousavi Jul 21 '20 at 18:49
  • @Berto99 Good idea.Indeed the [data structure](https://doc.qt.io/qt-5/qmetaobject.html) about a class in the meta-object system is more complicated than just a id , but that would possibly confuse the meta-object system if the class signatures of instances that should have the same ```QMetaObject``` instance differ.So ```moc``` will prevent you from using templates in the classes containing **Q_OBJECT**. – Parsa Mousavi Jul 21 '20 at 18:56
  • @ParsaMousavi well i've understood half of the things you have said, but sounds like something like what I want to say ahah – Alberto Sinigaglia Jul 21 '20 at 19:00
  • 1
    You can have a void* (or base type) signal in base class, and have template classes (corresponding to actual type) connect to template slots that reinterpret_cast back (much like what the moc does to begin with). You can also just take the auto generated moc code and add templates to the class definition, although I'd only do this in a private project. – jfh Jul 21 '20 at 19:52

1 Answers1

6

It is not possible* in standard Qt, as for Qt, as for these classes moc needs to be able to pre-process the class and generate the needed meta data structures. That is done before compilation, and for a template class that means that the type is not really defined yet.

However, some things are possible:

  • A QObject can have templated methods, as long as they are not marked as invokable, slot or signal.
  • You can create a template class that inherits a QObject-derived class. It cannot have a Q_OBJECT macro or add signals, slots or properties, but it can be a useful trick, for instance to create a templated generic QAbstractItemModel.
  • You could use Verdegris instead of moc. It uses a template-based alternative to moc that generates moc-compatible code. This should also allow for templated QObjects.

*) nothing is really impossible of course... If everything else fails, you can also implement everything moc provides yourself...

André
  • 570
  • 3
  • 7
  • 1
    Nice ! I haven't heard of **Verdigris**.And looks like there's a lot of [similarities](https://woboq.com/blog/verdigris-qt-without-moc.html) between MOC and **Verdigris** in terms of macros.So it's a deficiency within the MOC itself that cannot handle templates.In fact in real practice there's almost no case in which the use of templates and signal-slot mechanism at the same time is required.But your answer revealed the cause.Thanks :) – Parsa Mousavi Jul 21 '20 at 19:54
  • 1
    I would not call it a deficiency. There are historical reasons for moc being what it is. Verdegris used c++ that has only relatively recently become possible, while Qt with moc has been proven useful for some 25 years now. Before templated were even supported in the compilers Qt was supporting. – André Jul 21 '20 at 19:59
  • 1
    @André Maybe it was the best solution 25 years ago but certainly they didn't have to keep carrying it over to Qt5 and Qt6 (which already requires C++17 at the minimum). – pooya13 Dec 15 '21 at 19:28