简体   繁体   English

C ++ 11 std :: function和完美转发

[英]C++11 std::function and perfect forwarding

Why definition of std::function<>::operator() in the C++ standard is: 为什么在C ++标准中定义std :: function <> :: operator()是:

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

and not 并不是

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

?

One would think that to correctly forward parameters, we need the && and then use std::forward<ArgTypes>... in the function body when forwarding the call? 有人会认为要正确转发参数,我们需要&&然后在转发调用时在函数体中使用std::forward<ArgTypes>...吗?

I partially reimplemented std::function to test this and I found out that if I use the &&, I get "cannot bind 'xxx' lvalue to 'xxx&&'" from g++ when I try later to pass parameters by value to operator(). 我部分重新实现了std :: function来测试这个,我发现如果我使用&&,当我稍后尝试通过值将参数传递给operator()时,我从g ++中得到“无法将'xxx'左值'绑定到'xxx &&'” 。 I thought that I got enough grasp of the rvalue/forwarding concepts, but still I cannot grok this point. 我认为我对rvalue / forwarding概念有了足够的把握,但我还是不能理解这一点。 What am I missing? 我错过了什么?

Perfect forwarding only works when the function itself (in this case operator() ) is templated and the template arguments are deduced. 完美转发仅在函数本身(在本例中为operator() )被模板化并推导出模板参数时才有效。 For std::function , you get the operator() argument types from the template parameters of the class itself, which means they'll never be deduced from any arguments. 对于std::function ,您可以从本身的模板参数中获取operator()参数类型,这意味着它们永远不会从任何参数中推断出来。

The whole trick behind perfect forwarding is the template argument deduction part, which, together with reference collapsing, is what perfect forwarding is. 完美转发背后的整个技巧是模板参数推导部分,它与参考折叠一起,是完美的转发。

I'll just conveniently link to my other answer about std::forward here, where I explain how perfect forwarding (and std::forward ) works. 我只是方便地链接到我关于std::forward其他答案 ,在这里我解释了完美转发(和std::forward )的工作原理。

Note that std::function 's operator() doesn't need perfect forwarding, since the user himself decides what the parameters should be. 请注意, std::functionoperator()不需要完美转发,因为用户自己决定参数应该是什么。 This is also the reason why you cannot just add && to operator() ; 这也是你不能只将&&添加到operator() ; take this example: 举个例子:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM