C ++ 11 std :: function和完美转发 [英] C++11 std::function and perfect forwarding

查看:154
本文介绍了C ++ 11 std :: function和完美转发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why definition of std::function<>::operator() in the C++ standard is:

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

而不是

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

正确地转发参数,我们需要&&然后在转发呼叫时在函数体中使用 std :: forward< ArgTypes> ...

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 :: function来测试这个,我发现如果我使用&&&&,我得到不能绑定'xxx'lvalue'xxx&'放在g ++当我尝试以后传递参数按值到operator()。我认为我已经掌握了右值/转发概念,但是我还是不能理解这一点。

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(). I thought that I got enough grasp of the rvalue/forwarding concepts, but still I cannot grok this point. What am I missing?

推荐答案

完美转发只有在函数本身(在这种情况下)是模板化的,并且模板参数被推导出来。对于 std :: function ,您可以从类的模板参数中获取 operator()

Perfect forwarding only works when the function itself (in this case operator()) is templated and the template arguments are deduced. 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.

完美转发背后的整个技巧是模板参数扣除部分,它与

The whole trick behind perfect forwarding is the template argument deduction part, which, together with reference collapsing, is what perfect forwarding is.

我可以方便地链接到我的其他答案关于 std :: forward 在这里,我解释如何完美转发(和 std :: forward )。

I'll just conveniently link to my other answer about std::forward here, where I explain how perfect forwarding (and std::forward) works.

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

Note that std::function's operator() doesn't need perfect forwarding, since the user himself decides what the parameters should be. This is also the reason why you cannot just add && to 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
}

这篇关于C ++ 11 std :: function和完美转发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆