41

ラムダ関数を切断することは可能ですか? 「はい」の場合、どのように?

https://qt-project.org/wiki/New_Signal_Slot_Syntaxによると、 QObject::connect メソッドから返される を使用する必要がありますQMetaObject::Connectionが、そのオブジェクトをラムダ関数に渡すにはどうすればよいですか?

擬似コードの例:

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();
}
4

3 に答える 3

57

直接キャプチャ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.release();
        // ...
 });
于 2013-02-12T09:42:04.840 に答える