非常にまずい
C++ Advent Calender 2010に参加して19日目に僕でその日ってクリスマスと気付いて嬉しいような悲しいような。兎にも角にも現在5日目ですが、みんなネタが濃すぎて場違いな気がしてきて非常に危機感を感じておりますどうも。
『今のうちに書けるなら書いとこうか』という早い者勝ち理論を考えて、25日よりも早めに書きたいですね。
std::forwardの使い道
昨日、std::forwardの使い方、というかrvalueとlvalueの使い分け等々で色々聞かれてました(その時左辺参照とか右辺参照とか使ってすみませんでした。彼らを日本語直訳で呼ぶのは良くないです)。
rvalue referenceに関する説明は、
本の虫: rvalue reference 完全解説 本の虫: rvalue reference 補足
ほぼここで分かります。
std::forwardは単純にlvalueとrvalueをテンプレート内で適切に区別して使用したい場合に使用する関数でいいんじゃないでしょうか。
最近、それに出くわしたのはTypeErasureクラスを書いた時に、ある時はそのクラスが型を消したインスタンスを内部に持ってほしい、ある時はそのクラスは型を消したインスタンスへの参照として持ちたい、となった時です。
// 型を消したPCMへデコードするクラス class pcm_decodable { public: template< class T > pcm_decodable( T && decoder ) // : Base_( new pcm_decoder<T>( std::move(decoder) ) ); // lvalue reference で decoder を受け取った時、std::moveでpcm_decoderに渡すのは不適切。 : Base_( new pcm_decoder<T>( std::forward<T>(decoder) ); // std::forwardならば、T&とT&&のときを適切に処理して転送できる! private: struct pcm_decoder_base { }; template< class T > struct pcm_decoder : public pcm_decoder_base { }; std::unique_ptr<pcm_decoder_base> Base_; };
という風に、std::forwardはlvalue, rvalueかまでを判断してちゃんと転送してくれるものです。
代表例としてはmake_shared関数じゃないでしょうか。あの関数はstd::forwardで適切に引数をコンストラクタに渡してくれます。
要するにテンプレート引数の自動推論によるreference typeに適切に対処するための方法、と。