C++ – Is it possible to mix template-derived C++ classes with Qt’s Q_OBJECT

cqobjectqttemplates

In my application, I have the following class hierarchy:

class Word
{
    ...
}

template <typename T> class Dictionary
{
    ...
};

class WordDictionary : public Dictionary<Word>
{
    Q_OBJECT

    ...
}

The WordDictionary class parses a dictionary which takes a long time. I am running the parsing function from within a separate thread and I want it to be able to signal the GUI thread from time to time to provide progress updates based on the current line number being parsed. That's why I want it to be a Q_OBJECT. I tried to make the base class Dictionary a Q_OBJECT but got a message that Q_OBJECT templates are not supported. When I removed the macro, leaving only WordDictionary as Q_OBJECT, I get a bunch of error messages of the general form:

.\GeneratedFiles\Release\moc_dictionary.cpp(44) : error C2039: 'staticMetaObject' : is not a member of 'Dictionary'
with
[
T=Word
]

Is there anything I can do to make my template-derived WordDictionary class a Q_OBJECT other than hardcoding the template functions inside it, producing a lot of boilerplate code?

edit: Changing the template declaration to:

template <typename T> class Dictionary : public QObject

made the code compile. I'm not sure if I'm not doing something stupid and if this will work correctly, though.

Best Answer

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.

Related Topic