为什么std :: function构造函数或赋值之间有区别?

RTe*_*ete 8 c++ perfect-forwarding c++11 std-function

std::function类型擦除构造被定义为:

template< class F >
function( F f );
Run Code Online (Sandbox Code Playgroud)

赋值运算符定义为:

template< class F >
function& operator=( F&& f );
Run Code Online (Sandbox Code Playgroud)

(来源cppreference)

为什么构造函数获得f由价值而operator=获得f通过转发的参考?

Yak*_*ont 3

我只能猜测,但我猜这是因为它被添加到 C++ 中,而右值引用和转发引用被添加到语言中。

所以它的 API 的某些部分获得了转发引用,而另一些则没有。

有一个小优点:如果复制构造函数F可以抛出而移动不能抛出,std::function( F )则可以保证不抛出,而std::function( F const& )不能抛出。不同之处在于,在这种情况下,复制将在构造函数外部完成,但在传递非右值时,template<class F> function(F)复制将在构造函数内部完成。template<class F> function(F&&)

这并不是一个令人信服的理由。

它还将使指定 的 SFINAE 行为稍微容易一些function(F),但直到 C++11 很久之后才正式化,因此这不可能是原因。

的成本template<class F>function(F)很低——这是F完美转发版本的一个举措——所以它可能在任何人的优先级列表中都不是很高的更改(特别是因为它导致 的“可能抛出”测试发生微妙的变化function(F),因此理论上实际上可能会导致一些奇怪的代码被破坏)。