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

时间:2012-04-26 14:50:41

标签: c++ c++11 rvalue-reference

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

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

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

2 个答案:

答案 0 :(得分:5)

它可以防止像std::forward<std::string&>(std::string {})这样的奇怪内容。

行为由§20.2.3p2强制执行:

  

如果使用左值引用类型实例化第二个表单,则程序格式不正确。

答案 1 :(得分:5)

举例说明为什么将右值转换为左值是危险的,请参见N2951的用例C.此用例说明了如何轻松创建悬空引用。