如何使用不可复制的非可移动类的对象成员函数启动线程?

时间:2018-05-30 04:45:42

标签: visual-studio function c++11 stdthread

为什么以下代码无法在Visual Studio 2015中编译。

如果在ideone上运行,相同的代码可以正常工作。

class FooMutex
{
    std::mutex stm;
public:
    void foo() {}
};

int main()
{
    FooMutex o;
    std::thread t1(&FooMutex::foo, o);
}

Error is: C2664 'std::tuple<void (__thiscall FooMutex::* )(void),FooMutex>::
tuple(std::tuple<void (__thiscall FooMutex::* )(void),FooMutex> &&)'
: cannot convert argument 1 from 'void (__thiscall FooMutex::* )(void)' to 'std::allocator_arg_t'

1 个答案:

答案 0 :(得分:0)

有多种方法可以做你想做的事:

  • 传递指针:std::thread t1(&FooMutex::foo, &o);
  • 使用std::bindstd::thread t1(std::bind(&FooMutex::foo, &o));
  • 使用std::bindstd::thread t1(&FooMutex::foo, std::ref(o));
  • 使用lambda函数:std::thread t1([&o]() { o.foo(); });

第3和第2种方式与第1种方式基本相同。第4个实际上有可能成为最有效的一个,因为lambda的大小比包含指针和成员函数指针的可调用对象小,因此有更高的机会嵌入到内部std::function对象中,而不是在堆上分配。不是它改变了什么,但仍然。