Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt concurrent run, pass value by reference, but the memory address is different?

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
like image 399
movef Avatar asked Aug 02 '14 03:08

movef


2 Answers

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.

like image 169
AnT Avatar answered Nov 15 '22 23:11

AnT


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));
like image 40
Tobias Avatar answered Nov 15 '22 23:11

Tobias