std :: forward如何工作? [英] How does std::forward work?

查看:132
本文介绍了std :: forward如何工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

使用转发的优点


我知道它的作用,使用它,但我仍然不能包装我的头如何工作。请尽可能详细,并解释 std :: forward 如果允许使用模板参数扣除,则不正确。



我的困惑之一是:
如果它有一个名字,它是一个左值 - 如果这是为什么 std :: forward 当我通过事情&&& x vs 首先,让我们来看看 std:

:forward 根据标准执行:



§20.2.3[forward] p2


返回: static_cast<&& / code>


(其中 T 参数和 t 是传递的参数。)



现在请记住参考折叠规则:

  TR R 

T& & - >夯; // lvalue reference to cv TR - >左值引用T
T& &&& - >夯; // rvalue reference to cv TR - > TR(左值引用T)
T&& & - >夯; // lvalue reference to cv TR - >左值引用T
T&& &&& - > T&& // rvalue reference to cv TR - > TR(rvalue reference to T)

(无耻地从此答案。)



然后让我们来看看一个想要使用完美转发的类:

  template< class T> 
struct some_struct {
T _v;
template< class U>
some_struct(U& v)
:_v(static_cast< U&&>(v)){} //完美转发
// std :: forward语法糖为
};

现在示例调用:

  int main(){
some_struct< int> s1(5);
// in ctor:'5'是rvalue(int&& amp;),所以'U'被推导为'int',给出'int&'
// ctor after deduction: some_struct(int& v)'('U'=='int')
//带右值引用'v'绑定到值'5'
//现在我们'static_cast' 'v''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 'v'在这种情况下,是左值)
// huzzah,我们转发一个右值到'_v'的构造函数!

//注意,真正的魔法发生在这里
int i = 5;
some_struct< int> s2(i);
// in ctor:'i'是一个左值('int&'),所以'U'被推演为'int&', &&'
//应用参考折叠规则会产生'int&'(& +&& - >&)
// ctor后扣除和折叠:'some_struct int''''''''''$'$'$''''''$'$'''''''$' U&&',给出'static_cast< int& &&>(v)'
//折叠规则后:'static_cast< int&>(v)'
//这是一个无操作,'v' int&'
// huzzah,我们将一个左值转发给'_v'的构造函数!
}



我希望这个循序渐进的答案可以帮助你和其他人理解 std :: forward 工程。


Possible Duplicate:
Advantages of using forward

I know what it does and when to use it but I still can't wrap my head around how it works. Please be as detailed as possible and explain when std::forward would be incorrect if it was allowed to use template argument deduction.

Part of my confusion is this: "If it has a name, it's an lvalue" - if that's the case why does std::forward behave differently when I pass thing&& x vs thing& x?

解决方案

First, let's take a look at what std::forward does according to the standard:

§20.2.3 [forward] p2

Returns: static_cast<T&&>(t)

(Where T is the explicitly specified template parameter and t is the passed argument.)

Now remember the reference collapsing rules:

TR   R

T&   &  -> T&  // lvalue reference to cv TR -> lvalue reference to T
T&   && -> T&  // rvalue reference to cv TR -> TR (lvalue reference to T)
T&&  &  -> T&  // lvalue reference to cv TR -> lvalue reference to T
T&&  && -> T&& // rvalue reference to cv TR -> TR (rvalue reference to T)

(Shamelessly stolen from this answer.)

And then let's take a look at a class that wants to employ perfect forwarding:

template<class T>
struct some_struct{
  T _v;
  template<class U>
  some_struct(U&& v)
    : _v(static_cast<U&&>(v)) {} // perfect forwarding here
                                 // std::forward is just syntactic sugar for this
};

And now an example invocation:

int main(){
  some_struct<int> s1(5);
  // in ctor: '5' is rvalue (int&&), so 'U' is deduced as 'int', giving 'int&&'
  // ctor after deduction: 'some_struct(int&& v)' ('U' == 'int')
  // with rvalue reference 'v' bound to rvalue '5'
  // now we 'static_cast' 'v' to 'U&&', giving 'static_cast<int&&>(v)'
  // this just turns 'v' back into an rvalue
  // (named rvalue references, 'v' in this case, are lvalues)
  // huzzah, we forwarded an rvalue to the constructor of '_v'!

  // attention, real magic happens here
  int i = 5;
  some_struct<int> s2(i);
  // in ctor: 'i' is an lvalue ('int&'), so 'U' is deduced as 'int&', giving 'int& &&'
  // applying the reference collapsing rules yields 'int&' (& + && -> &)
  // ctor after deduction and collapsing: 'some_struct(int& v)' ('U' == 'int&')
  // with lvalue reference 'v' bound to lvalue 'i'
  // now we 'static_cast' 'v' to 'U&&', giving 'static_cast<int& &&>(v)'
  // after collapsing rules: 'static_cast<int&>(v)'
  // this is a no-op, 'v' is already 'int&'
  // huzzah, we forwarded an lvalue to the constructor of '_v'!
}

I hope this step-by-step answer helps you and others understand just how std::forward works.

这篇关于std :: forward如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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