关于qt:可变信号和通用lambda

Variadic signals and generic lambdas

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#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和/或QVariantList作为参数。

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

同样,您不能随意替换SIGNAL()SLOT(),它既是信号又是插槽,不能两者都用。

最后,您应该使用以下形式:

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

并且由于printInfoMessage使用的是自动参数,因此您可能需要使用qOverload强制执行自动解析:

1
QObject::connect(&a, &A::infoMessage, qOverload<QVariantList>(printInfoMessage));