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

时间:2016-09-13 13:31:21

标签: c++ c++11 std-function perfect-forwarding

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

template< class F >
function( F f );

赋值运算符定义为:

template< class F >
function& operator=( F&& f );

(来源cppreference)

为什么构造函数会在f通过转发引用获得operator=时按值获取f

1 个答案:

答案 0 :(得分:3)

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

因此,其API的某些部分获得了转发引用,而有些则没有。

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

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

这也会使指定function(F)的SFINAE行为变得更加容易,但是直到C ++ 11之后很久才形成这种行为,所以这不是原因。

template<class F>function(F)的费用很低 - F相对于完美转发版本的一次移动 - 所以它可能并没有在任何人的优先级列表上发生变化(特别是因为它会导致function(F)的测试发生微妙的变化,因此理论上可能导致一些奇怪的代码被破坏。