为什么一个std::thread
对象通过转发引用来接受函数参数,然后用 复制该对象decay_copy
?按值接受函数对象不是更容易吗?
一般来说,为什么不将函数模板化以便按值获取函数对象?引用性不能用reference_wrapper
s 来模仿吗(这会更明确,并且还可以方便地有一个成员operator()
来调用存储的函数)?
为什么一个std::thread
对象通过转发引用来接受函数参数,然后用 复制该对象decay_copy
?按值接受函数对象不是更容易吗?
一般来说,为什么不将函数模板化以便按值获取函数对象?引用性不能用reference_wrapper
s 来模仿吗(这会更明确,并且还可以方便地有一个成员operator()
来调用存储的函数)?
为什么一个
std::thread
对象通过转发引用来接受函数参数,然后用decay_copy复制该对象?按值接受函数对象不是更容易吗?
它必须在存储中具有函数对象的副本,只要它即将启动的线程持续存在,它就可以保证持续存在。
构造函数的参数std::thread
不会持续那么长时间,因为创建的行std::thread
可能在创建的线程结束之前很久就结束了。
所以它必须复制。如果它按值取参数,它会在调用构造函数时创建一个副本,然后必须将另一个副本复制到持久存储中。通过转发引用来获取它,它只会复制一份。
现在这个额外的副本可以被移动到,使额外的开销成为额外的移动。这仍然是额外的开销,因为并非所有构造都易于移动。
一般来说,为什么不将函数模板化以便按值获取函数对象?
因为这需要额外的move
.
不能用 reference_wrappers 来模仿引用性(这会更明确,并且还方便地有一个成员 operator() 来调用存储的函数)?
在您打算存储函数对象的情况下,通过转发引用获取可以节省一步,并且不需要函数对象获取代码的编写者进行太多额外的工作。
如果调用者传入一个引用包装器,则存储的值将是引用包装器,这具有不同的含义。