の実装はstd::move
基本的に次のようになります。
template<typename T>
typename std::remove_reference<T>::type&&
move(T&& t)
{
return static_cast<typename std::remove_reference<T>::type&&>(t);
}
のパラメーターstd::move
はユニバーサル参照 (転送参照とも呼ばれますが、ここでは転送しません) であることに注意してください。つまり、std::move
左辺値と右辺値の両方を使用できます。
std::string a, b, c;
// ...
foo(std::move(a)); // fine, a is an lvalue
foo(std::move(b + c)); // nonsense, b + c is already an rvalue
しかし、全体のポイントはstd::move
右辺値にキャストすることなので、なぜ右辺値にキャストできるのstd::move
でしょうか? std::move
左辺値のみを受け入れるとしたら、もっと理にかなっているのではないでしょうか?
template<typename T>
T&&
move(T& t)
{
return static_cast<T&&>(t);
}
その場合、無意味な式std::move(b + c)
によってコンパイル エラーが発生します。
上記の の実装はstd::move
、コードが見た目とまったく同じように動作するため、初心者にとってははるかに理解しやすいでしょう: 左辺値を取り、右辺値を返します。ユニバーサル参照、参照の折りたたみ、およびメタ関数を理解する必要はありません。
では、なぜstd::move
左辺値と右辺値の両方を取るように設計されたのでしょうか?