c++ 简要说明所要求的参考收缩规则:(1)A&&A> A&,(2)A \u0026\u0026 – > A&,(3)A \u0026\u0026&A&A和(4)A \u0026\u0026&

以下链接提供了4种引用形式的折叠(如果我是正确的,这些是唯一的4种形式):http://thbecker.net/articles/rvalue_references/section_08.html.

从链接:

  1. A& & becomes A&
  2. A& && becomes A&
  3. A&& & becomes A&
  4. A&& && becomes A&&

虽然我可以做出有根据的猜测,但我想简要的解释这些参考崩溃规则背后的理由.

一个相关的问题,如果我可能:这些引用崩溃规则在C 11内部由STL实用程序(如std :: move(),std :: forward()等)内部使用,在典型的真实用例中? (注意:我特别询问在C 11中是否使用引用折叠规则,而不是C 03或更早版本.)

我问这个相关问题,因为我知道这样的C 11实用程序,如std :: remove_reference,但是我不知道引用相关的实用程序,如std :: remove_reference是否常规地用于C11,以避免引用的需要 – 折叠规则,或它们是否与引用折叠规则结合使用.

最佳答案
参考折叠规则(除了A&& A& A&,C 98/03)存在的一个原因是:允许完美转发工作.

“完美”转发意味着有效地转发参数,就像用户直接调用函数一样(减去elision,由转发中断).用户可以通过以下三种值:lvalues,xvalue和prvalue,并且有三种方式可以通过(可能的常量)左值引用和(可能的常量)值来获取一个值:参考.

考虑这个功能:

template<class T>
void Fwd(T &&v) { Call(std::forward<T>(v)); }

按价值

如果调用通过值取其参数,则该参数必须进行复制/移动.哪一个取决于输入值.如果传入值是一个左值,那么它必须复制左值.如果传入值是rvalue(它们统称为x值和pr值),那么它必须从它移动.

如果您使用左值调用Fwd,则C的类型扣除规则意味着T将被推导为Type& amp;其中Type是左值的类型.显然,如果lvalue是const,它将被推导为const类型&参考折叠规则意味着类型& &安培;&安培;变成Type&对于v,一个左值引用.这正是我们需要调用的Call.用一个左值引用来调用它会强制一个副本,就好像我们直接调用一样.

如果您使用x值(即:某些类型&&表达式)调用Fwd,则T将被推导为类型& amp;&参考折叠规则说明Type&& &安培;&安培;变为类型&&再次,这是我们需要调用Call.使用非常量r值引用来调用它将强制移动/复制,就好像我们直接调用它一样.

如果您使用prvalue(即:类型临时表达式)调用Fwd,则T将被推导为类型.参考折叠规则给了我们类型& amp;& amp;&

通过左值引用

如果Call通过lvalue引用获取其值,那么只有当用户使用lvalue参数时才应该调用它.如果它是一个常量参考,那么它可以被任何东西(lvalue,xvalue,prvalue)调用.

如果你用一个左值调用Fwd,我们再次得到Type&作为v的类型,它将绑定到非const lvalue引用.如果我们使用const lvalue来调用它,我们得到const Type&,它只会绑定到Call中的一个const lvalue引用参数.

如果您使用xvalue命名Fwd,我们再次获得Type&&作为v的类型,这将不允许您调用一个接受非const lvalue的函数,因为xvalue不能绑定到非const lvalue引用.它可以绑定到一个const lvalue引用,所以如果Call使用了一个const&,我们可以用一个xvalue来调用Fwd.

如果您以普遍价值称呼Fwd,我们再次获得类型& amp;&您不能将临时传递给具有非常量左值的函数,因此我们的转发功能同样会阻止这样做.

通过rvalue引用

如果Call通过rvalue引用获取其值,那么只有在用户使用xvalue或lvalue参数时才应该调用它.

如果你用一个左值调用Fwd,我们得到Type& amp;这不会绑定到rvalue引用参数,因此导致编译错误.一个const类型&也不会绑定到一个rvalue引用参数,所以它仍然失败.这正是如果我们直接使用lval调用Call的话会发生什么.

如果您使用xvalue命名Fwd,我们将获得类型&& amp;它的作品(cv-qualification当然也是重要的).

使用prval也是一样.

的std ::前进

std :: forward本身以类似的方式使用引用折叠规则,以将传入的rvalue引用作为x值(作为类型&&是xvalues的函数返回值)和传入的左值引用作为左值(返回类型&)传递.

转载注明原文:c++ 简要说明所要求的参考收缩规则:(1)A&&A> A&,(2)A \u0026\u0026 – > A&,(3)A \u0026\u0026&A&A和(4)A \u0026\u0026& - 代码日志