[Interest] Lambda functions not reused by connect?

Alejandro Exojo suy at badopi.org
Thu Apr 23 20:13:54 CEST 2015


Hi.

I have a download progress signal connected to a mutable lambda. The lambda 
does something that can be done only once. In the real case I use a captured 
pointer, which after use becomes invalid, so I set it to nullptr and check its 
value before use. But on all invocations the pointer has the original value 
instead. This is a minimal test case that I think reproduces it well:

#include <QtCore>
#include <QtNetwork>

class Object : public QObject {
    Q_OBJECT
public:
    Object() {
        auto reply = 
qnam.get(QNetworkRequest(QUrl("http://upload.wikimedia.org/wikipedia/commons/f/f9/Platycercus_eximius_diemenensis_pair.jpg")));
        bool halfDownloaded = false;
        connect(reply, &QNetworkReply::downloadProgress,
                [halfDownloaded](qint64 received, qint64 total) mutable
        {
            static bool copy = halfDownloaded;
            qDebug() << "Progress:" << received << "of" << total;
            qDebug() << "half?" << halfDownloaded << "copy?" << copy;
            if (received >= (total/2) && !halfDownloaded) {
                qDebug() << "Setting to true. Should only be seen once";
                halfDownloaded = true;
                copy = true;
            }
        });
        connect(reply, &QNetworkReply::finished, this, []{ qApp->quit();});
    }
private:
    QNetworkAccessManager qnam;
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Object o;
    return a.exec();
}

#include "main.moc"


Here I added a "static bool copy" that acts as a workaround to keep the state 
across invocations. I want the "if" block that prints "should only be seen 
once" to be called only once, but it doesn't. Is this intended? I suppose that 
since lambdas are on-the-fly classes, each signal emission creates a new 
instance of the class, instead of one instance and several calls to 
operator(). Is that so?

Another way to do it would be to let the lambda disconnect itself, but it is 
quite difficult to capture the return of connect().

Greetings.

-- 
Alex (a.k.a. suy) | GPG ID 0x0B8B0BC2
http://barnacity.net/ | http://disperso.net



More information about the Interest mailing list