c++ - 在没有复制构造函数的对象的成员函数中启动 std::thread

标签 c++ multithreading stdthread

我想在一个没有复制构造函数的对象的成员函数处启动一个std::thread。在成员函数处启动线程的标准方法(例如参见 Start thread with member function )需要一个复制构造函数。我以为我可以通过使用 std::ref 来解决这个问题(例如参见 std::thread pass by reference calls copy constructor ),但没有成功。

这是我的代码。线程 t1 有效,但 t2 无效。如果我尝试取消注释这两行,它会给出:

error: attempt to use a deleted function 
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...); ^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/thread:357:5: note: 
in instantiation of function template specialization
'std::__1::__thread_execute<void (Dummy::*)(), std::__1::reference_wrapper<Dummy> , 1>' 
requested here __thread_execute(*__p, _Index()); ^ 
etc.

如何直接在 print() 处启动线程,而不需要 uselessFunction

另外,我想更好地理解错误。编译器提示哪个“删除的函数”?

#include <iostream>
#include <thread>
using std::cout;
using std::endl;

class Dummy {
public:
    std::atomic<bool> flag;  // atomic kills implicitly created copy constructor
    void print() { std::cout << "hello!" << std::endl; }
};

void uselessFunction(Dummy &d) {
    d.print();
}

int main() {
    Dummy d{};
    std::thread t1(uselessFunction, std::ref(d));  // this works
    // std::thread t2(&Dummy::print, std::ref(d)); // does not work
    t1.join();
    // t2.join();
}

最佳答案

std::thread 使用 std::invoke调用函数。 std::invoke 足够聪明,能够获取指向对象的指针并使用它调用成员函数。这意味着您可以将 t2 更改为

std::thread t2(&Dummy::print, &d);

并获得正确的行为。

关于c++ - 在没有复制构造函数的对象的成员函数中启动 std::thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52004854/

相关文章:

c++ - 对错误的 undefined reference 显示了我的函数 GTKMM C++ 的额外参数

c++ - C++ 二叉树类需要什么

c++ - 我可以同时调用 std::unordered_map 的这些成员函数吗?

java - 如何从多线程返回值?

c++ - vector 中的线程无法连接

c++ - 后续: Executing a member function of a class

c++ - 矩阵列比较

c++ - alignof(T*) 对于所有可能的类型都相同吗? sizeof(T*) 呢?

java - 用一个写入器线程替换写入输出流的多个线程 (Java)

c++ - 根据函数签名将可变参数模板中的类型转发为值/引用