可变信号和通用 lambda
Variadic signals and generic lambdas
是否可以创建可变 signal 和 connect 通用 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_tuple
和 std::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));
是否可以创建可变 signal 和 connect 通用 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_tuple
和 std::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));