在std :: forward如何接受右值? [英] In std::forward how does it accept rvalue?
问题描述
查看Scott Meyer的有效现代C ++ 第200-201页,建议的 std :: forward
的简化实现可能是正确实现在别处):
Looking at Scott Meyer's Effective Modern C++ pages 200-201, the suggested simplified implementation of std::forward
could be (did see the proper implementation elsewhere):
template <typename T>
T&& forward(std::remove_reference_t<T>& param)
{ return static_cast<T&&>(param); }
当接受右值Widget时,它变成:
And when accepting an rvalue Widget, it becomes:
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
现在,如果你使用替换代码,并执行:
Now, if you take that substituted code, and do:
struct Widget { };
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
template <typename T>
void G(T&& uref)
{ }
template <typename T>
void F(T&& uref)
{ G(forward(uref)); }
int main()
{
Widget x;
F(std::move(x));
}
我无法包装我的头,直接回答SO仍然是:<$> forward
参数 Widget& param
管理从F()接受 Widget&&
?通常gcc-5.0会抱怨非模板代码:
What I can't wrap my head around, and didn't see a direct answer on SO yet, is: in forward
how does parameter Widget& param
manage to accept Widget&&
from F()? Normally gcc-5.0 would complain like so with non-template code:
错误:类型为'Widget&'的非const引用无效初始化类型为'std :: remove_reference ::类型{aka Widget}'
error: invalid initialization of non-const reference of type ‘Widget&’ from an rvalue of type ‘std::remove_reference::type {aka Widget}’
(问题#27501400 几乎触及了这个主题,但不完全相同,它显示标准具有lvalue&和rvalue&& amp版本。)
(Question #27501400 nearly touches the topic, but not quite. It shows the standard as having both lvalue & and rvalue && versions.)
推荐答案
命名的右值引用是左值,
"Named rvalue references are lvalues",
$ b
so example works fine as noted in a comment.
但是,您的代码可以修改为
Nevertheless your code could be modified to
template <typename T>
void F(T && uref)
{
G(forward(move(uref)));
}
$ b
which is accepted by another overload (compare):
template<typename T>
T && forward(typename std::remove_reference<T>::type & t)
{
return static_cast<T &&>(t);
}
template<typename T>
T && forward(typename std::remove_reference<T>::type && t)
{
static_assert(!std::is_lvalue_reference<T>::value, "T is an lvalue reference");
return static_cast<T &&>(t);
}
第二个重载将用于右值。如果 T
是 Widget
或 Widget&&< / code >并且
Widget&
的assert失败。
The second overload will be used for rvalue. It works if T
is Widget
or Widget &&
and the assert fails for Widget &
.
这篇关于在std :: forward如何接受右值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!