いう、とても古いバージョンのものです。3年ごとに更新されます。古いバージョンを対象にするべきではありません。ベースにした新C++編を作成中です。特殊化テンプレートでは、テンプレート仮引数に当てはめる具体的な型に応じて、普通のクラスや関数をインスタンス化します。して生成されるクラスや関数のことを、特殊化と呼びます。ところで、あるクラステンプレートの設計を考えたとき、そのテンプレート仮引数に当てはめられる型の種類によっては、実装上、都合が悪いケースがあります。あるのは、次のような処理です。==演算子を使って比較します。この場合、std::strcmp関数によって比較される方が適切かもしれません。この例のように、テンプレート仮引数の具体的な型によって、処理内容を変更したいことがあります。これを可能にするための仕組みとして、完全特殊化(明示的特殊化)や部分特殊化が使えます。完全特殊化や部分特殊化は、テンプレート仮引数に特定の型が当てはめられたときにだけ使われる、特別版を定義する機能です。完全特殊化それではまず、完全特殊化の例を見ていきましょう。クラステンプレートの場合と、関数テンプレートの場合とがあるので、それぞれ個別に解説します。DataStoreクラステンプレートの例を解決してみます。std::endl;}実行結果:true完全特殊化を行う際には、まず、通常のテンプレートの定義を用意しておきます。これはこれまでの章とまったく同じように作ればいいです。して用意したテンプレートのことを、1次テンプレート(プライマリテンプレート)と呼びます。完全特殊化のためのクラス定義を別途用意します。これは、1次テンプレートが見える位置に書きます。<>」を付けることで、完全特殊化を行っていることを表す必要があります。クラス名の後ろに、テンプレート仮引数に当てはめられる具体的な型名を指定します。これを記述することで、この型がテンプレート仮引数に当てはめられたときにだけ、この完全特殊化されたクラスが使用されるようになります。あとは、1次テンプレートと同じ意味合いの内容になるように、メンバを書いていきます。感覚として意識して欲しいのは、1次テンプレート側と違い、完全特殊化のためのクラスは、具体的な型を使って記述されるという点です。ようなテンプレート仮引数は登場しません。テンプレートを使用する側は、特に何も意識する必要がありません。DataStoreクラスが使用され、それ以外の型を指定した場合には、DataStoreクラステンプレートをその型を使ってインスタンス化したクラスが使用されます。いう結果になっています。std::strcmp関数が使用されているからです。今度は、関数テンプレートの完全特殊化の例を挙げます。Length関数テンプレートを定義しています。char*型で表現された文字列の場合には、当然ながらメンバ関数がありません。char*型の場合にだけ、std::strlen関数を使わせようとしています。関数テンプレートの場合の完全特殊化は、クラステンプレートの場合とほぼ同様で、1次テンプレートとなる関数テンプレートを定義し、これが見える位置に、完全特殊化のための関数を定義します。<>」が必要である点も、クラステンプレートの場合と同様です。完全特殊化のための定義の方には、関数名の後ろに、テンプレート仮引数に当てはめる具体的な型名を指定します。これも、クラステンプレートの場合と同様ではありますが、関数テンプレートの場合は、実引数から型を推測しますから(第9章)、それによってコンパイラが判断可能であれば省略できます。省略する場合は、次のようになります。char*>」ではなくて「<char>」であることに注目してください。「char」と判断されます。当てはめられる型はあくまで「char」なのです。したがって、完全特殊化の側のテンプレート実引数は「char」が正解です。参照の方がシンプルで安全だと思われます。仮に以下のように参照に直すと、コンパイルが通らなくなります(呼び出し側も修正したとしても)。std::strlen(str);}これは、完全特殊化の方ではポインタが使われているため、引数の型が一致しないためです。完全特殊化はあくまでも、テンプレート仮引数の部分を具体化するだけですから、それ以外の部分が変わってはいけません。このケースでは、完全特殊化ではなくて、単に関数をオーバーロードすればいいでしょう。std::strlen(str);}これなら問題ありません。関数テンプレートと通常の関数があり、どちらにも適合するときには、通常の関数の方が優先される(第9章)ので、きちんと動作します。分かりづらいのですが、部分特殊化にはいくつかのパターンがありますが、どれも一言で言えば、「テンプレート仮引数の一部だけを特殊化する」ということです。テンプレート仮引数のうちの一部分だけしか特殊化されないので、言い換えると、特殊化されていないテンプレート仮引数が残っているということです。そのため、完全特殊化する場合と違い、部分特殊化によって作られるものはクラスではなく、クラステンプレートのままです。1つ目のパターンは、テンプレート仮引数の型の具体性を高めるような特殊化で、たとえば、T型のテンプレート仮引数に対して、T*型で特殊化するというものです。この場合、指定されたテンプレート実引数がポインタだった場合にだけ、特殊化されるということになります。ときには特殊化するというものです。新たなノンタイプテンプレート仮引数(第22章)に追加できます。部分特殊化は、クラステンプレートにのみ可能であり、関数テンプレートに対しては行えません。関数テンプレートの場合の一部は、オーバーロードを使うことで代替できます。【上級】関数の戻り値の型を指定するためにテンプレート仮引数を使うような関数テンプレートの場合、オーバーロードでは引数の型や個数でしか区別を付けられないので、対応できません。この場合は、クラステンプレートを用意して、そちらで部分特殊化し、そのメンバ関数を呼ぶように実装すれば対応可能です。それでは、部分特殊化の例を見ていきましょう。T*型で部分特殊化します。ds2.Print();}実行結果:1020DataStore<>::Printメンバ関数は、保持している値を出力しますが、ポインタ型を保持しているときには、指し示す先の値を出力します。T>」はそのまま必要です。<>」だと、完全特殊化を意味するので注意してください。複数個あるテンプレート仮引数の一部を特殊化する次の例は、2つあるテンプレート仮引数のうちの1つだけを特殊化するものです。Stackクラステンプレートです。クラステンプレートは2つあり、1つは要素の型、もう1つは要素数の上限値です。1要素の情報を持つように特殊化しています。場合にしていることと、考え方は同じです(【標準ライブラリ】第5章)。テンプレート仮引数の個数が増えるパターン次の例は、テンプレート仮引数の個数が変わるパターンです。40複数の要素を配列管理するクラステンプレートです。通常は、指定された型の要素を動的な配列を使って管理しますが、要素数が分かっている配列型を指定した場合には、静的な配列を使った実装を使用します。呼ばれる、テンプレートを活用した機能群があります。理解していける段階に来たはずです。コンテナ(STLコンテナ)について学んでみましょう。【標準ライブラリ】第4章に進み、概要を知ったら、第5章~第13章まで進めてください。続けて、第14章に進み、イテレータという概念について理解してください。【標準ライブラリ】編では、ほぼ全機能を網羅するリファレンスのようなページ作りをしているので、すべてを理解するのではなく、ざっくりとした概要を学ぶ程度で良いでしょう。【言語解説】編の本章までに解説されていない概念が登場することもあるので、その場合は、単に読み飛ばして良いです。T*型で部分特殊化する」において、ポインタであるかそうでないかによって、printメンバ関数の実装を変えられることを示しました。STLコンテナ、「vector」「list」「deque」「set」「map」は、それぞれどんなデータ構造を提供しますか?解答ページはこちら。当サイトの参考書籍一覧ページ。関する書籍を多数紹介。当サイトの参考Webサイト集。全般的な学習に有益なサイトを紹介。