C++0x では decltype によって「式の型」を得ることが出来ますが、
テンプレートメタプログラミングなんかで「ある型の変数を decltype 内で使いたい」って時には、
その変数をどうやって作るかが問題になります。
例えば T1 と T2 を乗算した結果の型が欲しいとかいう場合、
普通の型なら T1 と T2 が同じ型 T なら T になるでしょうが、
もしベクトルとか行列だったらダメですので、 decltype を使って取得したい。
でも、 decltype( T1 * T2 )
とは書けない。じゃあどうするか。
まず考えられるのが decltype( T1() * T2() )
ですが、
これは T1 と T2 に対して default constructible を要求してしまいますし、
T1 や T2 が参照型の場合にはダメダメです。
じゃあ T1 t1(); T2 t2();
という関数を作ってから、
decltype( t1() * t2() )
とすればいいじゃないか、というと、
それは T1 や T2 が noncopyable な場合にダメかもしれないし、
何より、イチイチ補助関数を定義するのが面倒です。
じゃあどうするかというと、ここはテンプレートで汎用的な補助関数を作ればよくて、
template<typename T> T&& value_of();
という関数 value_of を作れば、後は
decltype( value_of
とか書けて幸せ、
かと思いきや、今度は T が U&& の場合に困りますし、
そもそも、そういう補助関数は出来る事なら標準で欲しいよね。
と思ってたら、標準に declval ってのがありました。
規格: 20.3.4 Function template declval ( in N3092 p.491 )
template <class T> typename add_rvalue_reference<T>::type declval() noexcept; // as unevaluated
これを使えば、こう書けます:
decltype( std::declval<T1>() * std::declval<T2>() )
まぁ正直、普段は
template<typename T1, typename T2> auto f( T1 && t1, T2 && t2 ) -> decltype( t1 * t2 );
とか書けばいいので、
あまり使わない関数かと思います。
でも、覚えておくと、いざ必要になったときにオレオレ補助関数を作らなくて済むので
幸せになれるかなーと思いました。
あ、ヘッダは