Using QtConnurrent with lambda
-
The QT documentation is pretty terse suggesting using lambda to run QtConncurent .
" ... time consuming function here ..."
It does not elaborate any further.
So this code - after adding Function_TEST_A();
QFuture<int> future_TEST = QtConcurrent::run([](){ qDebug() << "compute"; return 42; }); Throws this error :
/mnt/sde5/QT_PROGRAMS_FULL/MDI_BT/MDI_BT/SUB_FT857/mainwindow_sub_ft857.cpp:328: error: 'this' cannot be implicitly captured in this context
Can anybody tell me why and how to fix it ?
-
The lambda itself is ok. It's a bit of a guessing game since you omitted the code that actually faults, but if you're calling
Function_TEST_A()
in that lambda and if that function usesthis
for anything then yeah, that's what you'll get.
Lambda needs to capture whatever you use inside it, so a simple fix to that would be capturing it all:[&]()
. You could be more explicit and capture only what you use, but I can't suggest anything without knowing the contents of that test function. -
@AnneRanch said in Using QtConnurrent with lambda:
Can anybody tell me why and how to fix it ?
There is nothing to fix. This code definitely works.
I guess the code which give this error is another one, but cannot understand why you don't want to show?
Do not make sense to me.Perhaps you should first understand how lambda functions works in C++ and how to define them before trying to use them.
There are many tutorials available on internet, my preferred is this one:
https://blog.feabhas.com/2014/03/demystifying-c-lambdas/hope this will help you.
-
@KroMignon Let me put it this way
I do RTFM and post what is said ability using lambda.
I post the error.IMHO the error shroud be enough to lead me to the fix.
The " start from how the world created" seem to be standard "answer". -
@Chris-Kawa Thanks - the test function is blank, no code , and does not return any values. I can change that and try "capture all".
Thanks. -
@AnneRanch said in Using QtConnurrent with lambda:
@Chris-Kawa Thanks - the test function is blank, no code , and does not return any values. I can change that and try "capture all".
Thanks.I need a clarification Here is the actual QT doc copy of using lambda in QtConncurent
QFuture<void> future = QtConcurrent::run([=]() { // Code in this block will run in another thread });
Here is how my test code looks like :
QFuture<void> future_LAMBDA_1 = QtConcurrent::run([=]() { Function_TEST(count); });
so
run executes between ( … )
lambda starts with [=]
and the “functor” is between { … }I assumed that { } is what QT doc calls “code to be executed “ , however I am lost how
lambda syntax gets to pass ( PARAMETER ) to it
[=])(parameter) …..The way it is coded now really takes no advantage of lambda – it almost looks as the stuff between {} should be the actual body of the function. I am trying to call the function - as codded now. .
And yes - I can execute Run function with or without (single ) parameter or with or without return value . It actually runs in a new thread !
Making slow progress... -
I reformatted your code snippets because they were so garbled it was hard to read. I hope you don't mind.
run executes between ( … )
No,
run
passes the function object given to it as a parameter to another thread to execute and returns immediately giving you a future object that you can use to wait for that asynchronous execution to end. It does not run the function object directly.lambda starts with [=]
and the “functor” is between { … }Again, no. The lambda is a functor, so this entire thing:
[](){}
. This whole thing is an object like anint
. It just happens to represent a functor and not a number. A functor, in simple terms, is something that executes code. It can be a function, likevoid func() {}
, it can be a class withoperator()
likestruct foo { operator(){} }
or it can be a lambda like[](){}
. These are all functors and they all can be used in aQtConcurrent::run
call.So, if you have a function that you want to run in another thread via QtConcurrent you don't need to wrap it in a lambda. You can just pass it directly.
Getting back to your original problem - the error says that you're using
this
inside of the lambda. If your test function is empty then the only way this would be true is if your test function itself is a member of a class. In that case you need an object to call it on and that object needs to be captured in the lambda context, so again, you need to capture this in the capture clause of the lambda.Btw. very little of this has to do with Qt.
QtConcurrent::run
just happens to take any functor, including lambdas, and it's just how lambdas work in C++. -
@Chris-Kawa The reason for using lambda approach - it looked as it would be simpler than to deal with still unclear way to "wrap" the function under run (...) . If I cannot figure out how to pass parameters using lambda, , I will take another look at NOT using lambda
It is not any simpler. .PS Can you tell me how to pass the parameters to lambda - if I use the "call to function "?
-
Can you tell me how to pass the parameters to lambda - if I use the "call to function "?
The arguments are just passed to
run
as additional arguments after the functor.
Here's an example. Say you have a function that takes an int:void SomeFunction(int value) { qDebug() << value; }
You can pass it directly to run like this:
int some_value = 42; QFuture<void> future = QtConcurrent::run(SomeFunction, some_value);
If you need to wrap it in a lambda you can do it too:
int some_value = 42; auto lambda = [](int v){ SomeFunction(v); }; QFuture<void> future = QtConcurrent::run(lambda, some_value);
or you can just inline it like you have in your code:
int some_value = 42; QFuture<void> future = QtConcurrent::run([](int v){ SomeFunction(v); }, some_value);
All these will work for free functions. If you want to call a member function of the class you're calling
run
from, then you need to go with a lambda and catchthis
in the lambda capture clause as you did above. Rest is the same. -
@AnneRanch said in Using QtConnurrent with lambda:
Let me put it this way
I do RTFM and post what is said ability using lambda.
I post the error.
IMHO the error shroud be enough to lead me to the fix.
The " start from how the world created" seem to be standard "answer".Let me answer this way, I never requests you to RTFM, the only thing I was trying to do was to improve your knowledge about lambda functions in C++.
Which is, in my eyes, the first step before trying to use them.I have given you a link to a well done explanation about how to use lambda in C++, which is much better a trying my self to do it. My English is not fluent enough to explain it in a better way.
So, if you had taken time to learn how to use lambda, you had found quickly why you got this error.
But this seems to be hard for you.I am always stomach by people who want to program but don't want to learn how to it. And which are always becomes aggressive when someone point out their lake of comprehension.
I am always pleased when someone gives me an explanation or links where I can find useful information to understand how to do what I want to do.