为什么std :: thread通过转发引用接受仿函数

时间:2016-07-23 22:42:38

标签: c++ multithreading c++11 c++14 forwarding-reference

为什么std::thread对象通过转发引用接受函数参数,然后使用decay_copy复制对象?通过值接受函数对象会不会更容易?

一般来说为什么不模拟函数以便按值获取函数对象?引用不能用reference_wrapper来模仿(更明确,也方便有成员operator()来调用存储的函数)?

1 个答案:

答案 0 :(得分:6)

  

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

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

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

所以它必须复制。如果它使用参数by-value,它将在调用构造函数时生成副本,然后必须将另一个副本复制到持久存储。通过转发引用来获取它,它使完全一个副本。

现在可以移动这个额外的副本,使额外的开销增加一个额外的动作。这仍然是额外的开销,因为并非所有构造都很便宜。

  

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

因为这要求额外的move

  

可以使用reference_wrappers来模仿引用(它更明确,并且还方便地使用成员operator()来调用存储的函数)?

在您打算存储函数对象的情况下,通过转发引用来保存移动,并且在函数对象的编写器部分中不需要额外的工作来获取代码。

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