Qt:Templated Q_Object Class

Why is it not possible to use Q_OBJECT with template classes?

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...

Templated Q_OBJECT base class

The code is correct. The mistake was in my qbs dependencies. File A.h just haven't been compiled and haven't been correctly included to the B_inh.h, so I had these linker errors

Is it possible to mix template-derived C++ classes with Qt's Q_OBJECT?

You can't do this directly but there are usable work-rounds. See the article here.

While it is theoretically possible for
moc to handle templates, it would be
extremely complex to implement, and
would be highly impractical to use:
For each template instantiation, moc
would have to generate the appropriate
meta-object code, and the generated
code would have to be included once
per link unit---which becomes a
nightmare to maintain once a template
class is used with the same template
parameter in different compilation
units.

If the signals and slots don't require
the template parameter to be part of
the prototype, the workaround is to
make a template class inherit a
QObject subclass that provides the
required signals and slots. If
signals and slots need to use the
template parameters, the Observer
pattern is an alternative.

templated class in Qt

http://www.parashift.com/c++-faq-lite/separate-template-fn-defn-from-decl.html

If you compile and (try to) link these two .cpp files, most compilers will generate linker errors. There are two solutions for this. The first solution is to physically move the definition of the template function into the .h file, even if it is not an inline function.

This solution may (or may not!) cause significant code bloat, meaning your executable size may increase dramatically (or, if your compiler is smart enough, may not; try it and see).
The other solution is to leave the definition of the template function in the .cpp file and simply add the line template void foo(); to that file:

// File "foo.cpp"
#include <iostream>
#include "foo.h"

template<typename T> void foo()
{
std::cout << "Here I am!\n";
}

template void foo<int>();

So for your case, you would have in your .cpp file:

#include "filter.h"

template <class T>
NumericFilter<T>::NumericFilter(int, int)
{

}

template NumericFilter<int>::NumericFilter<int>(int, int); // added line!!!

Tada! No compile errors!

BTW, parashift's explanations on templates in C++ are the best IMHO.

Hope that helps.



Related Topics



Leave a reply



Submit