可变信号和通用 lambda

Variadic signals and generic lambdas

是否可以创建可变 signalconnect 通用 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: error: process for main.cpp:18: Error: Template function as signal or slot

moc failed...

这里用宏 SLOT() 代替 &A::infoMessage 没有多大帮助。是否有任何解决方法来克服此限制?

我知道,有些答案会包含 std::make_tuplestd::index_sequence 的使用。但是有没有更简洁的解决方案?

使用模板没有直接的解决方法。其中一个原因是 moc 索引了所有信号和槽,这不能用于函数模板,因为函数模板将生成几个依赖于通常无法从 moc 访问的代码的函数。

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

一种解决方案是使用 QVariant and/or QVariantList 作为参数。


请注意,错误不是由 QObject::connect 行引起的,而是 class A.

中的信号声明引起的

另外,SIGNAL()SLOT()不能随意替换,它要么是一个信号,要么是一个插槽,不能两者兼而有之。

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

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

并且由于 printInfoMessage 使用自动参数,您可能需要使用 qOverload:

强制自动解析
QObject::connect(&a, &A::infoMessage, qOverload<QVariantList>(printInfoMessage));