c++11:为啥 std::forward 中的 static_assert 是必要的?
Posted
技术标签:
【中文标题】c++11:为啥 std::forward 中的 static_assert 是必要的?【英文标题】:c++11: why is static_assert in std::forward necessary?c++11:为什么 std::forward 中的 static_assert 是必要的? 【发布时间】:2012-04-26 14:50:41 【问题描述】:在 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;
【问题讨论】:
【参考方案1】:例如,为什么将右值作为左值转发是危险的,请参见N2951 的用例 C。这个用例展示了这样做如何使创建悬空引用变得容易。
【讨论】:
【参考方案2】:它可以防止像std::forward<std::string&>(std::string )
这样的奇怪事情。
该行为由 §20.2.3p2 规定:
如果第二种形式是用左值引用类型实例化的,则程序是非良构的。
【讨论】:
以上是关于c++11:为啥 std::forward 中的 static_assert 是必要的?的主要内容,如果未能解决你的问题,请参考以下文章
C++ STL应用与实现7: 如何使用std::forward_list 单链表 (since C++11)
为啥 std::forward_list::empty 有 [[nodiscard]] 而 std::forward_list::max_size 没有? [复制]