与Fowarding参考混淆
评论中说:
将LVALUE转发为LVALUE或RVALUE
但是返回值只是rvalue的参考,我想知道它是如何是lavlue或rvalue?这是否意味着返回的值是通用参考?如果是这样,什么决定如何将其推导为lvalue参考或rvalue参考?
另外,第二个过载返回完全相同的内容,为什么它在注释中仅作为无用参考的RVALUE参考说出?
template <class _Ty>
_NODISCARD constexpr _Ty&& forward(
remove_reference_t<_Ty>& _Arg) noexcept { // forward an lvalue as either an lvalue or an rvalue
return static_cast<_Ty&&>(_Arg);
}
template <class _Ty>
_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept { // forward an rvalue as an rvalue
static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
return static_cast<_Ty&&>(_Arg);
}
In the c++ std type_traits file below the first overloaded function, the comment says:
forward an lvalue as either an lvalue or an rvalue
However the return value is just an rvalue reference, I wonder how it could be either an lavlue or an rvalue? Does it mean the returned value is a universal reference? If so what decides how to deduce it to an lvalue reference or an rvalue reference?
Also the second overload returns exactly the same thing, why does it say in the comment only forwarding as a rvalue reference without lvalue reference?
template <class _Ty>
_NODISCARD constexpr _Ty&& forward(
remove_reference_t<_Ty>& _Arg) noexcept { // forward an lvalue as either an lvalue or an rvalue
return static_cast<_Ty&&>(_Arg);
}
template <class _Ty>
_NODISCARD constexpr _Ty&& forward(remove_reference_t<_Ty>&& _Arg) noexcept { // forward an rvalue as an rvalue
static_assert(!is_lvalue_reference_v<_Ty>, "bad forward call");
return static_cast<_Ty&&>(_Arg);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果
_TY
是rvalue参考或非参考,则_TY&amp;&amp;
is(通过参考删除规则)rvalue参考。因此,函数调用表达式将是xvalue(一种rvalue)。但是,如果
_ty
是对类型t
的LVALUE引用,则IE_TY = t&amp;
,则参考删除规则也暗示_TY&amp ;&amp; = T&amp; &amp;&amp; = t&amp;
。因此,函数调用将是LVALUE表达式。这是
std :: forward
的实现。_TY
的模板参数不打算(也不能)推导。相反,必须明确给出它。通常,
std :: forward
仅应以std :: forward&lt; u&gt;(u);
使用u
是转发参考参考表单的参数u&amp;&amp; u
在功能模板中使用u
模板参数。在这些条件下,如果通过
u
传递了rvalue,u
将被推荐为非参考,并且如果通过lvalue传递了u
将推荐给LVALUE参考。然后
std :: forward&lt; u&gt;(u)
将传递非参考或lvalue参考类型作为_TY> _TY
tostd :: forthrom to
thork to to
thork toefform std :: fromphst ::
相应地和以上规则,std :: forward&lt; u&gt;(u)
将具有相同的值类别(rvalue或lvalue)与转发参考u的参数相同
有。 (但是,它将prvalues和xvalues映射到xvalues。)在第二个超载中,该注释不会提到转发为lvalue,因为如果用户尝试使用这种方式,则
static_assert
将触发。在参数是rvalue时,不应允许使用lvalue参考模板参数调用std :: forward
。这与我上面讨论的预期用法不符。If
_Ty
is either a rvalue reference or a non-reference, then_Ty&&
is (by reference collapsing rules) a rvalue reference. Hence the function call expression will be a xvalue (a kind of rvalue).If
_Ty
is however an lvalue reference to typeT
, i.e._Ty = T&
, then the reference collapsing rules imply that also_Ty&& = T & && = T&
. So then the function call will be an lvalue expression.This is an implementation of
std::forward
. The template argument for_Ty
is not intended to (and can't be) deduced. Instead it must be given explicitly.Normally
std::forward
should only be used in the formstd::forward<U>(u);
whereu
is a forwarding reference parameter of the formU&& u
in a function template withU
a template parameter.Under these conditions, if a rvalue was passed for
u
,U
will be deduced to a non-reference and if an lvalue was passedU
will be deduced to an lvalue reference.Then
std::forward<U>(u)
will pass either a non-reference or an lvalue reference type as template argument for_Ty
tostd::forward
accordingly and by the rule above,std::forward<U>(u)
will have the same value category (rvalue or lvalue) as the argument to the forwarding referenceu
had. (However, it maps both prvalues and xvalues to xvalues.)In the second overload the comment doesn't mention forwarding as lvalue, because the
static_assert
will trigger if the user tried to use it that way. It should not be allowed to callstd::forward
with a lvalue reference template argument while the argument is a rvalue. That would not match the intended usage I discussed above.