c++qtlambda

Pass QString in Lambda Function


I want to pass a QString into a lambda slot-function to modify it further. Unfortunately the QString goes out of scope before reaching the slot, so I cannot append text. How can I ensure that the QString is not running out of scope to process it inside the lambda? A class member is no option for me.

// main.cpp
#include <QObject>
#include <qtclass.h>

int main(int argc, char* argv[])
{
    QtClass q;
    q.foo();
    emit q.bar();
}
// qtclass.h
#include <QObject>

class QtClass : public QObject
{
    Q_OBJECT

public:
    void foo()
    {
        QString msg = "Hello"; // the string is being modified depending on different situations
        if (boolFunc1())
           msg += " qt";
        if (!boolFunc2())
           msg += " 123";
        QObject::connect(this, &QtClass::bar, this, [&msg]()
            {
                msg.append(" World"); // access violation reading position, msg is out of scope
            });
    };

signals:
    void bar();
};

Solution

  • Since the lambda outlives the local variable msg, then the variable should be copied (removing &):

        QString msg = "Hello";
        msg += " qt";
        QObject::connect(this, &QtClass::bar, this, [msg]
            {
                msg.append(" World");
            });
    

    If msg is not used after these statements, then the variable can be moved:

        QString msg = "Hello";
        msg += " qt";
        QObject::connect(this, &QtClass::bar, this, [msg = std::move(msg)]
            {
                msg.append(" World");
            });
    

    msg.append(" World") seems to modify msg. Hence, the code does not compile, the lambda must be mutable:

    [msg = std::move(msg)]() mutable