在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;
}
答案 0 :(得分:5)
它可以防止像std::forward<std::string&>(std::string {})
这样的奇怪内容。
行为由§20.2.3p2强制执行:
如果使用左值引用类型实例化第二个表单,则程序格式不正确。
答案 1 :(得分:5)
举例说明为什么将右值转换为左值是危险的,请参见N2951的用例C.此用例说明了如何轻松创建悬空引用。