11

在我的应用程序中,我有以下类层次结构:

class Word
{
    ...
}

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

class WordDictionary : public Dictionary<Word>
{
    Q_OBJECT

    ...
}

WordDictionary 类解析需要很长时间的字典。我在一个单独的线程中运行解析函数,我希望它能够不时向 GUI 线程发出信号,以根据当前正在解析的行号提供进度更新。这就是为什么我希望它是一个 Q_OBJECT。我试图将基类 Dictionary 设为 Q_OBJECT,但收到一条消息,指出不支持 Q_OBJECT 模板。当我删除宏,只留下 WordDictionary 作为 Q_OBJECT 时,我收到一堆一般形式的错误消息:

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

除了对其中的模板函数进行硬编码,产生大量样板代码之外,我还能做些什么来使我的模板派生 WordDictionary 类成为 Q_OBJECT?

编辑:将模板声明更改为:

template <typename T> class Dictionary : public QObject

使代码编译。不过,我不确定我是否没有做一些愚蠢的事情,以及这是否能正常工作。

4

1 回答 1

15

您不能直接执行此操作,但有可用的工作轮次。请参阅此处的文章。

虽然理论上 moc 可以处理模板,但实现起来非常复杂,而且使用起来非常不切实际:对于每个模板实例化,moc 都必须生成适当的元对象代码,并且生成的代码将具有每个链接单元包含一次——一旦模板类在不同的编译单元中与相同的模板参数一起使用,这将成为一场噩梦。

如果信号和槽不需要模板参数是原型的一部分,解决方法是让模板类继承提供所需信号和槽的 QObject 子类。如果信号和槽需要使用模板参数,观察者模式是一个替代方案。

于 2010-11-21T14:04:19.387 回答