c ++ 11:为什么std :: forward中的static_assert是必要的?

Can*_*hiu 4 c++ rvalue-reference c++11

在move.h中,有两个重载 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);
}
Run Code Online (Sandbox Code Playgroud)

我看到static_assert是为了防止意外地将左值投射到左值.可以通过这种方式实现右值版本:

template<typename _Tp>
typename std::remove_reference<_Tp>::type&&         
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
    return __t;
}
Run Code Online (Sandbox Code Playgroud)

R. *_*des 5

它可以防止奇怪的事情std::forward<std::string&>(std::string {}).

该行为由§20.2.3p2强制执行:

如果第二种形式用左值引用类型实例化,则程序格式错误.


How*_*ant 5

作为一个例子,为什么它是危险的转发右值作为左值,看到的使用情况C N2951.此用例说明了如何轻松创建悬空引用.