std::function
类型擦除构造函数定义为:
template< class F >
function( F f );
赋值运算符定义为:
template< class F >
function& operator=( F&& f );
(来源cppreference)
为什么构造函数会在f
通过转发引用获得operator=
时按值获取f
?
答案 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)
的测试发生微妙的变化,因此理论上可能导致一些奇怪的代码被破坏。