C++ c++;11:为什么std::forward中的静态_断言是必要的?
在move.h中,有两个重载C++ c++;11:为什么std::forward中的静态_断言是必要的?,c++,c++11,rvalue-reference,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&am
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);
}
它可以防止像
std::forward(std::string{})
这样的奇怪事情
该行为由§20.2.3p2规定:
如果第二个表单是用左值引用类型实例化的,则程序是格式错误的
关于为什么将右值作为左值转发是危险的示例,请参见的用例C。这个用例展示了这样做如何使创建悬挂引用变得容易
template<typename _Tp>
typename std::remove_reference<_Tp>::type&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
return __t;
}