子类化模板类并连接到信号

时间:2017-08-08 00:37:36

标签: c++ qt templates

我正在尝试子类QQueue以添加一些功能。 实际上,我无法继承子类,但由于代码非常短,我重写了自己的实现:

#ifndef MYQUEUE_H
#define MYQUEUE_H

#include <QObject>
#include <QtCore/qlist.h>

QT_BEGIN_NAMESPACE

template <class T>
class MyQueue : public QList<T>
{
Q_OBJECT

public:
    // compiler-generated special member functions are fine!
    inline void swap(MyQueue<T> &other) Q_DECL_NOTHROW { QList<T>::swap(other); } // prevent QList<->QQueue swaps
#ifndef Q_QDOC
    // bring in QList::swap(int, int). We cannot say using QList<T>::swap,
    // because we don't want to make swap(QList&) available.
    inline void swap(int i, int j) { QList<T>::swap(i, j); }
#endif
    inline void enqueue(const T &t) { QList<T>::append(t); emit enqueued(); }
    inline T dequeue() { return QList<T>::takeFirst(); }
    inline T &head() { return QList<T>::first(); }
    inline const T &head() const { return QList<T>::first(); }

signals:
    void enqueued();
};

QT_END_NAMESPACE

#endif // MYQUEUE_H

基本上,无论什么东西入队,它都会发出信号。 我不知道将该信号绑定到插槽的正确语法:

MyQueue<QString> queue;
connect(&queue, &MyQueue::enqueued, this, &MainWindow::process_queue);
  

错误:'模板类MyQueue'在没有模板参数的情况下使用     connect(&amp; queue,&amp; MyQueue :: enqueued,this,&amp; MainWindow :: process_queue);                        ^

它表示我正在使用MyQueue(即模板类)而未指定模板参数(QString)。

我试图添加它,但我做错了:

connect(&queue, &MyQueue<QString>::enqueued, this, &MainWindow::process_queue);
  

错误:没有匹配函数来调用'MainWindow :: connect(MyQueue ,void(MyQueue :: )(),MainWindow *,void(MainWindow :: *)())'< / p>

连接这样一个信号的正确语法是什么?

2 个答案:

答案 0 :(得分:2)

使用moc作为信号和插槽连接;它不支持模板。如果您对理由感兴趣,可以在此处详细了解此决定:http://doc.qt.io/qt-5/why-moc.html

也就是说,您在示例中显示的所有功能都可以在QStringList中使用,因此您可以将其视为此选项中的一个选项。

答案 1 :(得分:1)

根据我的评论......你可能会MyQueue从具有所需信号的合适基类继承。

class MyQueueBase: public QObject {
  Q_OBJECT;
public:
  virtual ~MyQueueBase ()
    {}
signals:
  void enqueued();
};

然后MyQueue变成......

template<class T>
class MyQueue: public MyQueueBase,
               public QList<T>
{
public:

  /*
   * All as before but without the signal declaration.
   */
};

使用上面的代码可以连接到基类或派生类...

connect(&queue, &MyQueueBase::enqueued, this, &MainWindow::process_queue);
connect(&queue, &MyQueue<QString>::enqueued, this, &MainWindow::process_queue);