Effective C++ メモ
第 7 章 テンプレートとジェネリックプログラミング
41 項 暗黙のインターフェースとコンパイル時ポリモーフィズムを理解しよう
覚えておくこと
- クラスとテンプレートは、どちらも、インターフェースとポリモーフィズムをサポートする。
- クラスのインターフェースは明示的で、主に関数のシグネチャによって表現される。ポリモーフィズムは、仮想関数を通して、実行時に実現される。
- テンプレーパラメータのインターフェースは暗黙的(非明示的)で、有効な式によって表現される。ポリモーフィズムは、テンプレートの具体化や関数オーバーロードの解決を通して、コンパイル時に実現される。 これは読んだままの意味。
42 項 typename の2つの意味を理解しよう
覚えておくこと
- テンプレートパラメータを宣言するときには、class と typename のどちらを使ってもよい。 これは class T と typename T は同じということ。
- ネストされた依存型名を指定するときには typename を使う。ただし、派生クラスを定義するときの基底クラスの指定と、初期化子リスト内での基底クラスの指定では typename を使わない。 ネストされた依存型名というのは、テンプレート内で T::const_iterator xxx のような T に依存する型のこと。
43 項 テンプレート化された基底クラス内の名前へのアクセス方法を知っておこう
覚えておくこと
- テンプレート化された基底クラスの内の名前を派生クラスで使うには、その名前に this-> を付けるか、using 宣言をするか、直接基底クラスを示す修飾をしなければならない。 これはテンプレート化された基底クラスのメンバをコンパイラは検索しないためです。
44 項 パラメータに依存しないコードはテンプレートから外に出そう
覚えておくこと
-
テンプレートは、複数のクラスや関数を生成する。そのため、テンプレートのパラメータに依存しない部分は、コードの膨張を招く。 これは、テンプレートクラス内で、テンプレートパラメータに依存しない部分のコードは、コードの膨張の元凶になるということ。
-
テンプレートの非型パラメータによるコードの膨張は、しばしば、テンプレートパラメータを関数の引数やクラスのデータメンバに置き換えることで、防ぐとことができる。 型ではないテンプレートパラメータを使用する場合は、引数にしてしまえばコードの膨張を抑えられるということ。
-
テンプレートの型パラメータによるコードの膨張は、バイナリ表現が同じ型同士で実装を共有するようにして軽減することができる。 int と long や様々なポインタなどの共通のバイナリの場合は、実装を共有することでコードの重複を防ぐことができる。
45 項 「すべての互換型」を受け取るためにメンバ関数テンプレートを使おう
覚えておくこと
- 互換な型のすべてを受け入れる関数を作るためには、メンバ関数テンプレートを使おう。 関数テンプレートを使って互換型を受け入れる関数を作るべき。
- テンプレートによって一般化されたコピーコンストラクタ・一般化されたコピー代入演算子を宣言しても、通常のコピーコンストラクタ:コピー代入演算子を宣言する必要がある。 これはそのままの意味。
46 項 型変換をさせたいなら、メンバでない関数をクラステンプレートの中で定義しよう
覚えておくこと
- クラステンプレートに、*this を含むすべての”引数”について暗黙の型変換をサポートする関数が必要なら、クラステンプレートの中でその関数を friend 宣言しよう。
47 項 型の情報に関しては traits クラスを使おう
覚えておくこと
- traits クラスは、型に関する情報をコンパイル時に知るのに使える。これはテンプレートとテンプレートの特化を利用して実装される。
- オーバーロードと traits クラスを使って、型に関する ( if-else のような ) 条件分岐をコンパイル時に行うことができる。
28 項 テンプレートメタプログラミングを意識しよう
覚えておくこと
- テンプレートメタプログラミングは、仕事を実行時からコンパイル時に移すことができる。それにより、エラーをコンパイル時に見つけ、実行時のパフォーマンスをよくすることができる。
- TMP はポリシ(選択)の組み合わせで通常のコードを生成するのにも使える。また、特定の型に対して不適切なコードを生成しないように使うこともできる。