变元信号和通用lambda

时间:2017-04-27 08:50:50

标签: qt c++11 signals-slots c++17 generic-lambda

是否可以创建可变的信号连接通用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并没有多大帮助。是否有任何解决方法可以克服这种限制?

我知道,有些答案会包含std::make_tuplestd::index_sequence内容的使用。但有没有那么冗长的解决方案?

1 个答案:

答案 0 :(得分:1)

拥有模板没有直接的解决方法。原因在于moc索引所有信号和槽,而功能模板不能这样做,因为函数模板将根据通常无法从moc访问的代码生成多个函数。

我认为你不能用元组工作,比如这些也是模板。

解决方案可能是使用QVariant和/或QVariantList作为参数。

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

此外,您无法随意替换SIGNAL()SLOT(),它可能是信号一个广告位,也不能同时替换。{/ p>

最后你应该使用这个表格:

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

由于printInfoMessage使用自动参数,您可能需要使用qOverload强制自动解决:

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