Question

I use QtConcurrent::run to run a function, and pass value by reference, but the memory address of value is different.

But if I pass value by pointer, the address is the same! I can't figure it out. Do I miss something?

Here's code.

void ptr(QString* s)
{
    qDebug() << "pass by ptr: " << s;
}

void ref(QString& s)
{
    qDebug() << "pass by ref: " << &s;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString str;
    QFuture<void> f1 = QtConcurrent::run(ptr, &str);
    f1.waitForFinished();

    QFuture<void> f2 = QtConcurrent::run(ref, str);
    f2.waitForFinished();

    qDebug() << "address of str: " << &str;

    return a.exec();
}

Output:

pass by ptr:  0x28fefc
pass by ref:  0x525de4
address of str:  0x28fefc
Was it helpful?

Solution

QtConcurrent::run creates internal copies of all arguments that you pass to it. Your thread function is then given access to these copies, not to the original arguments. Passing something by raw reference does not prevent creation of a copy. In other words, QtConcurrent::run enforces pass-by-value semantics internally.

The address that you see in the ref function is the address of that internal copy.

For this reason, if you specifically want access to the original object, instead of a naked reference you have to use something with pointer semantics or with "copyable reference" semantics.

OTHER TIPS

If you want/need to use a reference use std::ref. The new code would be:

#include <functional>
...

QFuture<void> f2 = QtConcurrent::run(ref, std::ref(str));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top