使用成员函数启动线程 [英] Start thread with member function

查看:123
本文介绍了使用成员函数启动线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用一个成员函数构造一个 std :: thread ,它不带任何参数并返回 void 。我不能找出任何工作的语法 - 编译器抱怨无论什么。实现 spawn()的正确方法是它返回一个 std :: thread $ c> test()?

  #include< thread& 
class blub {
void test(){
}
public:
std :: thread spawn(){
return {test}
}
};


解决方案

  #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 , 这个);
}






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



上面描述的语法是根据INVOKE定义(§20.8.2.1):


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


  • 类型T的对象或对
    类型T的对象的引用或对从T导出的类型的对象的引用;

  • ((* t1)。* f )(t 2,...,t N)当f是指向类T的成员函数的指针并且t1不是在先前的
    项中描述的类型之一时;

  • t1。* f当N == 1且f是指向类T的成员数据的指针,t 1是类型T的对象,或者是对类型T的对象的

    引用,或者引用从T导出的

    类型的对象;当N == 1时,

  • (* t1)。* f,f是指向成员数据的指针在所有其他情况下,类T和t 1不是前一项中描述的类型之一;

  • f(t1,t2,...,tN)






我想指出的另一个一般事实是,默认的线程构造函数将复制所有传递给它的参数。这样做的原因是参数可能需要超过调用线程,复制参数保证。相反,如果你想真正传递一个引用,可以使用 std :: ref std :: reference_wrapper >。

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

通过这样做,你承诺你会保证参数仍然存在






请注意,上述所有内容也可以应用于 std :: async std :: bind


I am trying to construct a std::thread with a member function that takes no arguments and returns void. I can't figure out any syntax that works - the compiler complains no matter what. What is the correct way to implement spawn() so that it returns a std::thread that executes test()?

#include <thread>
class blub {
  void test() {
  }
public:
  std::thread spawn() {
    return { test };
  }
};

解决方案

#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();
}

EDIT: Accounting your edit, you have to do it like this:

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


UPDATE: I want to explain some more points, some of them have also been discussed in the comments.

The syntax described above is defined in terms of the INVOKE definition (§20.8.2.1):

Define INVOKE (f, t1, t2, ..., tN) as follows:

  • (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of type T or a reference to an object of a type derived from T;
  • ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous item;
  • t1.*f when N == 1 and f is a pointer to member data of a class T and t 1 is an object of type T or a
    reference to an object of type T or a reference to an object of a
    type derived from T;
  • (*t1).*f when N == 1 and f is a pointer to member data of a class T and t 1 is not one of the types described in the previous item;
  • f(t1, t2, ..., tN) in all other cases.


Another general fact which I want to point out is that by default the thread constructor will copy all arguments passed to it. The reason for this is that the arguments may need to outlive the calling thread, copying the arguments guarantees that. Instead, if you want to really pass a reference, you can use a std::reference_wrapper created by std::ref.

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

By doing this, you are promising that you will take care of guaranteeing that the arguments will still exist when the thread operates on them.


Note that all the things mentioned above can also be applied to std::async and std::bind.

这篇关于使用成员函数启动线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆