Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++11: why is static_assert in std::forward necessary?

In move.h, there're two overloads of forward

template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{
    return static_cast<_Tp&&>(__t);
}

template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
    static_assert(
        !std::is_lvalue_reference<_Tp>::value,
        "template argument substituting _Tp is an lvalue reference type"
    );
    return static_cast<_Tp&&>(__t);
}

I see the static_assert is to prevent accidently casting a rvalue to a lvalue. Can the rvalue version be implemented this way:

template<typename _Tp>
typename std::remove_reference<_Tp>::type&&         
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
    return __t;
}
like image 818
Candy Chiu Avatar asked Dec 17 '22 01:12

Candy Chiu


1 Answers

As an example as to why it is dangerous to forward an rvalue as an lvalue, see use case C of N2951. This use case shows how doing so makes it easy to create dangling references.

like image 97
Howard Hinnant Avatar answered Jan 03 '23 11:01

Howard Hinnant