6

为什么一个std::thread对象通过转发引用来接受函数参数,然后用 复制该对象decay_copy?按值接受函数对象不是更容易吗?

一般来说,为什么不将函数模板化以便按值获取函数对象?引用性不能用reference_wrappers 来模仿吗(这会更明确,并且还可以方便地有一个成员operator()来调用存储的函数)?

4

1 回答 1

6

为什么一个std::thread对象通过转发引用来接受函数参数,然后用decay_copy复制该对象?按值接受函数对象不是更容易吗?

它必须在存储中具有函数对象的副本,只要它即将启动的线程持续存在,它就可以保证持续存在。

构造函数的参数std::thread不会持续那么长时间,因为创建的行std::thread可能在创建的线程结束之前很久就结束了。

所以它必须复制。如果它按值取参数,它会在调用构造函数时创建一个副本,然后必须将另一个副本复制到持久存储中。通过转发引用来获取它,它只会复制一份。

现在这个额外的副本可以被移动到,使额外的开销成为额外的移动。这仍然是额外的开销,因为并非所有构造都易于移动。

一般来说,为什么不将函数模板化以便按值获取函数对象?

因为这需要额外的move.

不能用 reference_wrappers 来模仿引用性(这会更明确,并且还方便地有一个成员 operator() 来调用存储的函数)?

在您打算存储函数对象的情况下,通过转发引用获取可以节省一步,并且不需要函数对象获取代码的编写者进行太多额外的工作。

如果调用者传入一个引用包装器,则存储的值将是引用包装器,这具有不同的含义。

于 2016-07-24T02:35:44.500 回答