断开Qt5中的lambda函数

时间:2013-02-12 08:49:11

标签: c++ lambda qt5

是否可以断开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();
}

3 个答案:

答案 0 :(得分:37)

如果直接捕获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.clear();
        // ...
    });

答案 1 :(得分:0)

ecatmur的答案中的上下文解决方案是最简单的选择,但是我认为使用智能指针会使它更难理解。我会改用原始指针:

QObject *context = new QObject(this);
connect(sender, &Sender::signal, context, [context] {
  delete context;
  // ...
});

答案 2 :(得分:0)

您可以将conn定义为.h文件中的私有变量。 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();
}