是否可以断开lambda函数的连接?如果"是",怎么办?
根据https://qt-project.org/wiki/New_Signal_Slot_Syntax我需要使用从QObject::connect方法返回的QMetaObject::Connection
,但是如何将该对象传递给lambda函数呢?
伪代码示例:
QMetaObject::Connection conn = QObject::connect(m_sock, &QLocalSocket::readyRead, [this](){
QObject::disconnect(conn); //<---- Won't work because conn isn't captured
//do some stuff with sock, like sock->readAll();
}
如果直接捕获conn
,则通过复制捕获未初始化的对象,这将导致未定义的行为。您需要捕获一个智能指针:
std::unique_ptr<QMetaObject::Connection> pconn{new QMetaObject::Connection};
QMetaObject::Connection &conn = *pconn;
conn = QObject::connect(m_sock, &QLocalSocket::readyRead, [this, pconn, &conn](){
QObject::disconnect(conn);
// ...
}
或者使用共享指针,开销稍大:
auto conn = std::make_shared<QMetaObject::Connection>();
*conn = QObject::connect(m_sock, &QLocalSocket::readyRead, [this, conn](){
QObject::disconnect(*conn);
// ...
}
在Qt 5.2中,您可以使用上下文对象:
std::unique_ptr<QObject> context{new QObject};
QObject* pcontext = context.get();
QObject::connect(m_sock, &QLocalSocket::readyRead, pcontext,
[this, context = std::move(context)]() mutable {
context.reset();
// ...
});
ecatmur答案中的上下文解决方案是最简单的选项,但我认为使用智能指针会使其难以理解。我更喜欢使用原始指针:
QObject *context = new QObject(this);
connect(sender, &Sender::signal, context, [context] {
delete context;
// ...
});
您可以在.h文件中将conn
定义为私有变量。QMetaObject::Connection conn
在lambda函数中,可以使用conn
并断开连接。
conn = QObject::connect(m_sock, &QLocalSocket::readyRead, [=](){
QObject::disconnect(conn); //<---- Won't work because conn isn't captured
//do some stuff with sock, like sock->readAll();
}