Reputation: 131
I want to create a thread of the function ahrs thats in my AHRS class. This function is in an infinite loop and calcs something the whole time and puts those calculations in variables. I want to pass those variables to my PID
int main() {
AHRS* a = new AHRS();
std::thread ahrs(a->ahrs());
PID* p = new PID();
float pitch;
while(1) {
pitch = a->getPitch();
std::cout << "pitch: " << pitch << " pid: " << p->getError(0, pitch, 1) << std::endl;
usleep(100000);
}
}
but i get the error
main_ahrs.cpp: In function ‘int main()’:
main_ahrs.cpp:26:28: error: invalid use of void expression
my ahrs.cpp looks like this:
#include "AHRS.h"
AHRS::AHRS() {
//something
}
AHRS::~AHRS() {}
void AHRS::ahrs() {
//something
while(1) {
//something
}
}
float AHRS::getPitch() {
//return something
}
float AHRS::getRoll() {
//return something
}
float AHRS::getYaw() {
//return something
}
thanks for your help
Upvotes: 2
Views: 6433
Reputation: 275385
Lambda is your friend.
int main() {
AHRS* a = new AHRS();
std::thread ahrs(a->ahrs());
what the above does is it calls a->ahrs()
(in main
), takes its return value and passes it to the thread
constructor. This isn't what you want.
Instead:
AHRS* a = new AHRS();
std::thread ahrs([a]{a->ahrs();});
will create a closure (or lambda) that consists of "do a call of a->ahrs()
".
It then passes that closure to std::thread
, which runs it on a different thread.
The [a]
says "this is a closure, and it captures a (copy of) a
". Then the body {a->ahrs();}
says what the closure does.
In general, passing lambdas to std::thread
is easier to reason about than passing the alternatives. There is a modest problem in that move-parameters require C++14 to work.
Using std::bind
or the variardic constructor of std::thread
are alternatives. I prefer passing code to passing data in this case, and passing a lambda closure is basically passing code.
Upvotes: 2
Reputation: 13443
Try like this:
#include <functional>
and then:
std::thread ahrs(std::bind(&AHRS::ahrs, a));
The way you are doing, you are calling the a->ahrs()
method, that returns void
. You must pass in to std::thread
something that can be called: a function pointer, or something like that, not void
.
In this case of my suggestion, you will pass to std::thread
the return from std::bind
, that is a callable object built with a pointer to the method and a pointer to the AHRS
object.
Upvotes: 2
Reputation: 385144
a->ahrs()
That is not how you name a function. That is how you call an expression and use its result for something. The result of the function is of void
type (that is, there isn't one) so using this function call as an expression (and certainly for a function reference/object/handle/wrapper/pointer!) is just not going to work.
The function is called AHRS::ahrs
.
A further complication is that it is a member function, so you have to bind the implicit this
parameter, like so:
std::thread ahrs(std::bind(&AHRS::ahrs, a));
The binding creates a sort of pseudo-function reference that already has the first argument sorted out for you, so that you (or, in this case, the thread
code, which has no ability or desire to guess what the object instance should be) does not need to.
Conveniently, thread
can do the binding for you, though, so:
std::thread ahrs(&AHRS::ahrs, a);
should suffice.
Upvotes: 4