在std :: forward如何接受右值? [英] In std::forward how does it accept rvalue?

查看:194
本文介绍了在std :: forward如何接受右值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

查看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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆