p685〜p690まで

さてさて、以前やったテンプレートの補足事項がここででてきました。
http://d.hatena.ne.jp/niso1985/20080505/1209998856
http://d.hatena.ne.jp/niso1985/20080506/1210086809

テンプレート引数

テンプレート引数にはtypename以外も取れるよっていうお話。

・テンプレート引数にはクラステンプレートを取ることができる。
例)(ちょっとややこしい)

// とりあえず普通のクラステンプレートを用意
template <typename T>
class HogeTemp2
{
public:
	T ret() { return m; }
	void push(T val) { m = val; }
private:
	T m;
};

// TEMPL2テンプレート仮引数は1つのテンプレート引数を持つクラステンプレートを意味する
// ここで、TEMPL2のテンプレート引数の名前はデフォルト引数を指定しなければ書かなくてもよい
// 理由はこのテンプレートクラス内でその名前は使用しないから。
template <template <typename> class TEMPL2>
class HogeTemp3
{
public:
	void Run()
	{
		m_.push(1);
		cout << m_.ret() << endl;
	}
private:
	TEMPL2<int> m_; // テンプレート実引数を渡す
};

int main()
{
	// TEMPL2がHogeTemp2に置き換わる。
	HogeTemp3<HogeTemp2> hoge3;
	hoge3.Run();
	return 0;
}

・テンプレート引数には静的な整数定数や静的なポインタ(静的変数や関数、メンバ関数のアドレス)をとることができる
例)

// とりあえず静的な整数定数版
// 普通に変数を宣言するようにテンプレート引数を指定する
template <int I>
class HogeTemp4
{
public:
	static const int VALUE = 1 << I;
};

int main()
{
	// テンプレート実引数に静的な整数値を指定
	cout << HogeTemp4<1>::VALUE << endl;
	// テンプレートなので、引数毎に実体が生成される
	cout << HogeTemp4<3>::VALUE << endl;
	return 0;
}

やばい、p689のコラムに書いてあるコードがわからん。

p689のコラム:配列の要素数の取得法より抜粋

template <typename T, size_t N>
char (*ARRAY_SIZE_(T (*)[N]))[N];

なんか、関数ポインタ指定する時に似ている気もするが・・・。シンタックスがわからない・・・。これはもうちょっと先勉強してから戻ってこんといかんぽいな。

テンプレートの特殊化もついでにやろうと思ったけど眠い・・・。ので明日。やっぱりテンプレートは難しいなぁ。