0

是否可以创建可变参数信号并将通用 lambda连接为slot?我的意思是这样的(比如说,所涉及函数的所有定义在需要的地方都是可见的(例如在实例化点)):

#include <QCoreApplication>
#include <QObject>
#include <QTime>

class A
    : public QObject
{
    Q_OBJECT

public :

    A(QObject * const parent = Q_NULLPTR)
        : QObject{parent}
    { ; }

signals :

    template< typename ...Ts >
    void infoMessage(Ts... args);

public slots :

    void run()
    {
        emit infoMessage("Started at ", QTime::currentTime());
    }

};

#include <QTimer>
#include <QtDebug>

#include "main.moc"

int main(int argc, char * argv [])
{
    QCoreApplication a{argc, argv};
    A a;
    auto printInfoMessage = [&] (auto... args)
    {
        (qInfo() << ... << args);
    };
    QObject::connect(&a, SIGNAL(infoMessage), printInfoMessage);
    QTimer::singleShot(0, &a, &A::run);
    return a.exec();
}

目前它给出了一条错误消息:

AUTOGEN:错误:main.cpp 的进程:18:错误:模板函数作为信号或槽

moc失败了...

这里宏SLOT()而不是&A::infoMessage没有太大帮助。是否有任何解决方法可以克服此限制?

我知道,其中一些答案将包含使用 ofstd::make_tuplestd::index_sequence东西。但是有没有那么冗长的解决方案?

4

1 回答 1

1

拥有模板没有直接的解决方法。一个原因是 moc 索引所有信号和插槽,而对于函数模板无法做到这一点,因为函数模板将生成几个函数,具体取决于通常无法从 moc 访问的代码。

我不认为你可以让它与元组一起工作,比如这些也是模板。

一个解决方案可能是使用 QVariant 和/或 QVariantList 作为您的论点。


请注意,错误不是由QObject::connect行引起的,而是A类中的信号声明引起的。

此外,您不能随意更换SIGNAL()SLOT()它要么是信号,要么插槽,不能两者兼而有之。

最后你应该使用这种形式:

QObject::connect(&a, &A::infoMessage, printInfoMessage);

由于 printInfoMessage 使用自动参数,您可能需要使用以下命令强制自动解析qOverload

QObject::connect(&a, &A::infoMessage, qOverload<QVariantList>(printInfoMessage));
于 2017-04-27T09:09:26.393 回答