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&lt;std::string&amp;&gt;(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 没有? [复制]

C++11 std::forward(配合&&右值引用)

C++11 std::forward(配合&&右值引用)

std::move和std::forward

std::move与std::forward