visual-studio - 如何使用不可复制不可移动类的对象成员函数启动线程?
问题描述
为什么下面的代码无法在 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'
解决方案
有多种方法可以做你想做的事:
- 改为传递指针:
std::thread t1(&FooMutex::foo, &o);
- 使用
std::bind
:std::thread t1(std::bind(&FooMutex::foo, &o));
- 使用
std::bind
:std::thread t1(&FooMutex::foo, std::ref(o));
- 使用 lambda 函数:
std::thread t1([&o]() { o.foo(); });
第三种和第二种方式与第一种方式基本相同。第 4 个实际上有可能成为最有效的一个,因为 lambda 将比包含指针和成员函数指针的可调用对象具有更小的大小,因此更有可能嵌入到内部std::function
对象中,而不是在堆上分配。并不是说它改变了什么,但仍然如此。
推荐阅读
- ssl - 在 JBoss EAP 6.4 中禁用主机名验证
- reactjs - 属性...在类型“IntrinsicAttributes & ...”上不存在
- c# - HttpResponse.TransmitFile 方法(但对于多个文件)?
- node.js - how to host angular and node js project on the shared hosting (cpanel or plesk)?
- awesome-wm - 当 input_passthrough 为真时,awesome-wm wibox 对鼠标信号没有反应
- c++ - 无法使用 CMake 编译 MagickWand
- spring-data-jpa - SimpleJdbcCall 跳过第一个输入参数
- c - 将引号中的字符串传输到 C 中的 ascii2 字节数组
- sql - 是否有任何查询我们必须只写我们不想显示的列?SQL / Laravel
- python - 熊猫按年分组,日期产生虚假值