15

为什么 C++ 标准中 std::function<>::operator() 的定义是:

R operator()(ArgTypes...) const;

并不是

R operator()(ArgTypes&&...) const;

?

有人会认为,要正确转发参数,我们需要 && ,然后std::forward<ArgTypes>...在转发调用时在函数体中使用?

我部分重新实现了 std::function 来测试它,我发现如果我使用 &&,当我稍后尝试按值传递参数给 operator() . 我认为我对右值/转发概念有足够的了解,但我仍然无法理解这一点。我错过了什么?

4

1 回答 1

17

完美转发仅在函数本身(在本例中operator())被模板化并推导出模板参数时才有效。对于std::function,您从operator()本身的模板参数中获取参数类型,这意味着它们永远不会从任何参数中推导出来。

完美转发背后的全部技巧是模板参数推导部分,与引用折叠一起,这就是完美转发。

我将方便地链接到关于此处的其他答案std::forward,我将在其中解释完美转发(和std::forward)的工作原理。

请注意,std::function'soperator()不需要完美转发,因为用户自己决定参数应该是什么。这也是你不能只添加&&到的原因operator();举个例子:

void foo(int){}

int main(){
  // assume 'std::function' uses 'ArgTypes&&...' in 'operator()'
  std::function<void(int)> f(foo);
  // 'f's 'operator()' will be instantiated as
  // 'void operator()(int&&)'
  // which will only accept rvalues
  int i = 5;
  f(i); // error
  f(5); // OK, '5' is an rvalue
}
于 2012-06-21T10:00:48.120 回答