为什么std::thread
对象通过转发引用接受函数参数,然后使用decay_copy
复制对象?通过值接受函数对象会不会更容易?
一般来说为什么不模拟函数以便按值获取函数对象?引用不能用reference_wrapper
来模仿(更明确,也方便有成员operator()
来调用存储的函数)?
答案 0 :(得分:6)
为什么
std::thread
对象通过转发引用接受函数参数,然后使用decay_copy复制对象?按值接受函数对象不是更容易吗?
它必须在存储中有一个功能对象的副本,只要它即将启动的线程持续,它就可以保证持续。
构造std::thread
的函数参数不会持续那么长,因为创建std::thread
的行可以在创建的线程结束之前很久就结束。
所以它必须复制。如果它使用参数by-value,它将在调用构造函数时生成副本,然后必须将另一个副本复制到持久存储。通过转发引用来获取它,它使完全一个副本。
现在可以移动这个额外的副本,使额外的开销增加一个额外的动作。这仍然是额外的开销,因为并非所有构造都很便宜。
一般来说,为什么不模拟函数以便按值获取函数对象?
因为这要求额外的move
。
可以使用reference_wrappers来模仿引用(它更明确,并且还方便地使用成员operator()来调用存储的函数)?
在您打算存储函数对象的情况下,通过转发引用来保存移动,并且在函数对象的编写器部分中不需要额外的工作来获取代码。
如果调用者传入了一个引用包装器,那么存储的值将是引用包装器,它具有不同的含义。