読者です 読者をやめる 読者になる 読者になる

ポリシークラスってなんぞや?〜その5〜

1章1.4節 テンプレートが希望の光を投げる(後半)

というわけで、テンプレートを使った際の問題点ですが、

  • 構造を特殊化することはできません。
  • メンバ関数の特殊化はスケーラビリティがありません。
  • ライブラリの開発者は複数のデフォルト値を提供できません。

という3点です。



構造を特殊化することはできません。

テンプレートを単独で使用するだけでは、クラスの構造(そのデータ・メンバ)を
特殊化することはできません。特殊化できるのは関数だけです。

わからんです。「クラスの構造(そのデータ・メンバ)を特殊化すること」もできる気がする。
例えば、以下のような記述は可能。(gcc3.4.4で確認)

struct A{
};

//ジェネリックな実装
template<class T>
struct Hoge {
	int x;
};

//特殊化
template<>
struct Hoge<A> {
	int x, y, z;
};

上記のコードは、クラスの構造(そのデータ・メンバ)を特殊化していると言えると思うのだけれど…。それとも、「テンプレートを単独で使用するだけでは」の解釈がミソなんだろうか?


メンバ関数については、その関数だけを取り出して特殊化することができる。しかし、データ・メンバを特殊化するためには、クラス全体を特殊化する必要性がある。そのことを言っているのだろうか?


メンバ関数の特殊化はスケーラビリティがありません。

テンプレート・パラメータを複数指定したテンプレートにおけるメンバ関数群を特殊化することはできない。
つまり、

template <class T, class U>
class Hoge
{
	void hoge(){...ジェネリックな実装...}
}

//以下はコンパイルエラー
template <class U>
void Hoge<char, U>::hoge()
{
	...特殊化した実装...
}

上記のようなコードはコンパイルエラーとなるということらしい。
しかし、これをもって「スケーラビリティがない」と言っているのがよくわからじ。
スケーラビリティってなんぞや?

より細かく、実装を選択できるってことだろうか?


つまり、テンプレートを使用したクラスでも、ジェネリックな実装と、完全な特殊化での実装とで、実装をわけることはできるけれども、それ以上、細かいことはできない。
たとえば、「このテンプレート引数が指定されていたら(他の引数がなんであろうと)、この関数の挙動は、こーいう風にしてー。」っという指定はできない。
こーいう細かい設定ができることを「スケーラビリティがある」と言い、「できないことをスケーラビリティがない」と言っているんではあるまいか?
「こーいう細かい設定」のあたりの定義が自分の中では、いまだ曖昧だけれど…。



ライブラリの開発者は複数のデフォルト値を提供できません。

クラス・テンプレートの実装者がメンバ関数それぞれに対して提供できるデフォルトの実装は、
たかだか1つだけです。

うん、これは、なんとなくわかる。

template<class T>
class Hoge{
	void hoge(){cout << "default type" << endl;}
};

デフォルトの実装ってのは、つまり、特殊化していないtemplate指定の実装ってことだろう。
上のコードのhoge関数のデフォルトの実装は、間違いなく1つ。複数記述する方法はない。