私は、C++ and Beyond 2012 カンファレンスでのUniversal References に関する Scott Meyers の講演を見てきましたが、これまでのところすべてが理にかなっています。ただ、私も気になっていたところで、50分くらいで観客から質問が。Meyers は、答えは慣用的ではなく、頭がおかしくなるので気にしないと言いますが、私はまだ興味があります。
提示されたコードは次のとおりです。
// Typical function bodies with overloading:
void doWork(const Widget& param) // copy
{
// ops and exprs using param
}
void doWork(Widget&& param) // move
{
// ops and exprs using std::move(param)
}
// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param) // forward => copy and move
{
// ops and exprs using std::forward<T>(param)
}
要点は、右辺値参照を取得すると、右辺値があることがわかっているため、それが右辺値でstd::move
あるという事実を保持する必要があるということです。ユニバーサル参照 ( T&&
、ここでT
は推定型)を取得する場合std::forward
、それが左辺値または右辺値である可能性があるという事実を保持したいと考えています。
問題はstd::forward
、関数に渡された値が左辺値か右辺値かを保持し、std::move
その引数を右辺値にキャストするだけなので、std::forward
どこでも使用できるかということです。を使用するすべての場合とstd::forward
同じように動作しますか、または Meyers の一般化によって見落とされている動作の重要な違いはありますか?std::move
std::move
マイヤーズが正しく言っているように、それは完全に慣用的ではありませんが、次のようにも の有効な使用法であるため、誰もがそれを行うべきだと示唆しているわけではありませんstd::move
。
void doWork(Widget&& param) // move
{
// ops and exprs using std::forward<Widget>(param)
}