查看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&& 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&amp;'类型的非const引用
(Question #27501400几乎触及了这个主题,但并不完全。它显示标准同时包含左值和右值以及右值和版本。)
答案 0 :(得分:0)
“命名的右值引用是左值”,
因此,如评论中所述,示例工作正常。
然而,您的代码可以修改为
template <typename T>
void F(T && uref)
{
G(forward(move(uref)));
}
被另一个重载(比较)接受:
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 &&
并且Widget &
的断言失败,则此方法有效。