使用线程和对象无效使用void表达式

时间:2015-07-24 19:02:24

标签: c++ multithreading object

我想在我的AHRS类中创建函数的线程。这个函数处于无限循环中并且整个时间计算某些东西并将这些计算放在变量中。我想将这些变量传递给我的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);
    }   
}

但我收到了错误

main_ahrs.cpp: In function ‘int main()’:
main_ahrs.cpp:26:28: error: invalid use of void expression

我的ahrs.cpp看起来像这样:

#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
}

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

a->ahrs()

这不是你如何命名一个函数。这就是你如何调用表达式并将其结果用于某事。函数的结果是void类型(也就是说,没有一个),因此使用此函数调用作为表达式(当然对于函数引用/对象/句柄/包装器/指针!)不会起作用。

该函数名为AHRS::ahrs

更复杂的是它是一个成员函数,所以你必须绑定隐式this参数,如下所示:

std::thread ahrs(std::bind(&AHRS::ahrs, a));

绑定创建了一种伪函数引用,它已经为你排序了第一个参数,以便你(或者,在这种情况下,thread代码,它没有能力或想要猜测对象实例应该是什么)不需要。

方便的是,thread可以为你做绑定,所以:

std::thread ahrs(&AHRS::ahrs, a);

应该足够了。

答案 1 :(得分:1)

试试这样:

#include <functional>

然后:

std::thread ahrs(std::bind(&AHRS::ahrs, a));

你正在做的方式是调用返回a->ahrs()的{​​{1}}方法。您必须传递给void可以调用的东西:函数指针或类似的东西,而不是std::thread

在我的建议的情况下,您将从void传递给std::thread,这是一个使用指向方法的指针和指向std::bind的指针构建的可调用对象对象

答案 2 :(得分:0)

Lambda是你的朋友。

int main() {
  AHRS* a = new AHRS();
  std::thread ahrs(a->ahrs());

上述内容是调用 a->ahrs()(在main中),获取其返回值并将其传递给thread构造函数。这不是你想要的。

相反:

  AHRS* a = new AHRS();
  std::thread ahrs([a]{a->ahrs();});

将创建一个由“调用a->ahrs()”组成的闭包(或lambda)。

然后将该闭包传递给std::thread,它在不同的线程上运行它。

[a]说“这是一个闭包,它捕获了a的副本”。然后身体{a->ahrs();}说出闭包的作用。

一般来说,将lambda传递给std::thread比传递替代品更容易理由。移动中存在一个适度的问题 - 参数需要C ++ 14才能工作。

使用std::bindstd::thread的变量构造函数是替代方案。在这种情况下,我更喜欢将代码传递给传递数据,并且传递lambda闭包基本上是传递代码。