4

move.h には、次の 2 つのオーバーロードがあります。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;
}
4

2 に答える 2

6

みたいな変なことを防いでくれstd::forward<std::string&>(std::string {})ます。

この動作は、§20.2.3p2 によって義務付けられています。

2 番目の形式が左辺値参照型でインスタンス化されている場合、プログラムは不適切な形式です。

于 2012-04-26T15:01:36.920 に答える
6

右辺値を左辺値として転送することが危険な理由の例として、N2951のユース ケース C を参照してください。この使用例は、そうすることでダングリング参照を簡単に作成できることを示しています。

于 2012-04-26T15:12:11.773 に答える