In std::forward how does it accept rvalue?

谁都会走 提交于 2019-12-11 02:40:30

问题


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); }

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));
}

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:

error: invalid initialization of non-const reference of type ‘Widget&’ from an rvalue of type ‘std::remove_reference::type {aka Widget}’

(Question #27501400 nearly touches the topic, but not quite. It shows the standard as having both lvalue & and rvalue && versions.)


回答1:


"Named rvalue references are lvalues",

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)));
}

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);
}

The second overload will be used for rvalue. It works if T is Widget or Widget && and the assert fails for Widget &.



来源:https://stackoverflow.com/questions/29041246/in-stdforward-how-does-it-accept-rvalue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!