【发布时间】:2015-03-13 20:20:02
【问题描述】:
查看 Scott Meyer 的 Effective Modern C++ 第 200-201 页,std::forward 的建议简化实现可能是(确实在其他地方看到了正确的实现):
template <typename T>
T&& forward(std::remove_reference_t<T>& param)
{ return static_cast<T&&>(param); }
而当接受一个右值Widget时,它变成:
Widget&& forward(Widget& param)
{ return static_cast<Widget&&>(param); }
现在,如果您使用该替代代码,然后执行以下操作:
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 会像这样抱怨非模板代码:
错误:从“std::remove_reference::type {aka Widget}”类型的右值初始化“Widget&”类型的非常量引用无效
(Question #27501400 几乎触及了这个话题,但并不完全。它表明标准同时具有左值 & 和右值 && 版本。)
【问题讨论】:
-
命名的右值引用是左值;真正的右值被单独的重载接受。
-
@T.C.这正是我忽略的方面,谢谢。
-
如果它有名字,它就是一个左值。所以
uref是一个左值。 -
@JasonM 实际上,我已经通过电子邮件向 Scott 发送了完全相同的问题,因为我认为这是一个错误。他基本上忽略了右值重载,因为他想不出任何用例。我最近问过这个here
标签: c++ c++11 perfect-forwarding