为了账号安全,请及时绑定邮箱和手机立即绑定

使用成员函数启动线程

使用成员函数启动线程

C++ C
长风秋雁 2019-05-29 17:14:54
使用成员函数启动线程我试图std::thread用一个不带参数和返回的成员函数构造一个void。我无法弄清楚任何有效的语法 - 编译器无论如何都会抱怨。实现的正确方法是什么,spawn()以便返回std::thread执行的test()?#include <thread>class blub {   void test() {   }public:   std::thread spawn() {     return { test };   }};
查看完整描述

4 回答

?
哈士奇WWW

TA贡献1799条经验 获得超6个赞

#include <thread>#include <iostream>class bar {public:
  void foo() {
    std::cout << "hello from member function" << std::endl;
  }};int main(){
  std::thread t(&bar::foo, bar());
  t.join();}

编辑:计算你的编辑,你必须这样做:

  std::thread spawn() {
    return std::thread(&blub::test, this);
  }

更新:我想解释一些问题,其中一些也在评论中讨论过。

上述语法是根据INVOKE定义(第20.8.2.1节)定义的:

定义INVOKE(f,t1,t2,...,tN)如下:

  • (t1。* f)(t2,...,tN)当f是指向类T的成员函数的指针时,t1是类型为T的对象或对类型为T的对象的引用或对类型T的引用源自T的类型的对象;

  • ((* t1)。* f)(t2,...,tN)当f是指向类T的成员函数的指针时,t1不是前一项中描述的类型之一;

  • t1。* f当N == 1且f是指向类T的成员数据的指针时,t 1是类型T 
    的对象或对类型为T的对象的引用或对从中
    派生的类型的对象的引用吨;

  • (* t1)。* f当N == 1且f是指向类T的成员数据的指针时,t 1不是前一项中描述的类型之一;

  • f(t1,t2,...,tN)在所有其他情况下。


我要指出的另一个一般事实是,默认情况下,线程构造函数将复制传递给它的所有参数。原因是参数可能需要比调用线程更长,复制参数保证了这一点。相反,如果您想真正传递引用,则可以使用std::reference_wrapper创建的std::ref

std::thread (foo, std::ref(arg1));

通过这样做,您承诺在线程对它们进行操作时,您将保证参数仍然存在。


请注意,上面提到的所有内容也可以应用于std::asyncstd::bind


查看完整回答
反对 回复 2019-05-29
?
月关宝盒

TA贡献1772条经验 获得超5个赞

由于您使用的是C ++ 11,因此lambda-expression是一个很好的清洁解决方案。

class blub {
    void test() {}
  public:
    std::thread spawn() {
      return std::thread( [this] { this->test(); } );
    }};

因为this->可以省略,它可以缩短为:

std::thread( [this] { test(); } )

要不就

std::thread( [=] { test(); } )


查看完整回答
反对 回复 2019-05-29
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

@ hop5和@RnMss建议使用C ++ 11 lambdas,但是如果你处理指针,你可以直接使用它们:

#include <thread>#include <iostream>class CFoo {
  public:
    int m_i = 0;
    void bar() {
      ++m_i;
    }};int main() {
  CFoo foo;
  std::thread t1(&CFoo::bar, &foo);
  t1.join();
  std::thread t2(&CFoo::bar, &foo);
  t2.join();
  std::cout << foo.m_i << std::endl;
  return 0;}

输出

2

这个答案重写的样本将是:

#include <thread>#include <iostream>class Wrapper {
  public:
      void member1() {
          std::cout << "i am member1" << std::endl;
      }
      void member2(const char *arg1, unsigned arg2) {
          std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
      }
      std::thread member1Thread() {
          return std::thread(&Wrapper::member1, this);
      }
      std::thread member2Thread(const char *arg1, unsigned arg2) {
          return std::thread(&Wrapper::member2, this, arg1, arg2);
      }};int main() {
  Wrapper *w = new Wrapper();
  std::thread tw1 = w->member1Thread();
  tw1.join();
  std::thread tw2 = w->member2Thread("hello", 100);
  tw2.join();
  return 0;}


查看完整回答
反对 回复 2019-05-29
  • 4 回答
  • 0 关注
  • 764 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信