p691〜pまで
だいぶ間が開きましたが、続きのテンプレートの特殊化から。
テンプレートの特殊化
・テンプレートの特殊化とは型ごとにテンプレートの定義を変更すること。
・特殊化をすると完全に型が決まってしまうので、実装はヘッダファイルに記述することができない。
・簡単な特殊化の例。コード自体に意味はなし。// 基本となるテンプレート template <typename T> class Hoge { pubic: static const char* hoge = "hoge" }; // クラス宣言での特殊化 // Hoge<int>の特殊化 // 既存のHoge内のメンバ宣言は全て無視される template<> class Hoge<int> { public: static const char* hoge = "int"; }; // 実体定義での特殊化 // Hoge<char>の特殊化 // そのメンバのみが特殊化される template<> const char* Hoge<char>::hoge = "char";
部分特殊化
・クラス宣言形式の特殊化では必ずしもすべてのテンプレート引数を特定する必要はない。これを部分特殊化と呼ぶ。
// こんな感じでintだけ特殊化みたいな template <typename T> class Hoge<T, int>{}; // テンプレート引数の型が同じ場合に特殊化とか template <typename U> class Hoge1<U, U>{}; // 一方がポインタとか template <typename V> class Hoge2<V, V*>{};・pair構造体テンプレートを用いることで、テンプレート引数を増やすことができる。
template<typename T> class Hoge { }; // Hogeテンプレートは1つまでの型しか許容していないが、pairを用いることで増やすことができる。 // 結局はpairで部分特殊化しただけ。 template<typename FIRST, typename SECOND> class Hoge< pair<FIRST, SECOND> > { };
汎整数昇格
・intより下の型(バイト数が少ない型?short, char, bool)が式中に現れた場合、その値はintかunsigned intに暗黙キャストされる。これを汎数昇格という。
・暗黙にキャストされたとしてもサイズはint, unsigned intの方が大きいため、汎整数昇格が行われる前後で値は変化しない。
・ただし、このような場合には注意が必要。(unsigned short)0に~を作用させて0xFFFF(65535)にしようとすると、汎整数昇格が行われ、~(int)(unsigned short)0となり、0xFFFFFFFF(-1)となってしまう。
この場合でもunsigned short型の変数に結果を代入するとオーバーフローを起こし、結果的には0xFFFFが得られるが、十分に注意しなければならない。
これでテンプレートは終了。pairとか正直使い方よくわからなかったので、ちょうどいい勉強になったかも。でもテンプレートはやっぱり使いどころが難しい気がする。
久々に勉強しましたが、なかなか面白い。やっぱり続けないといけませんね。だが眠い・・・。