C++が他の数多ある言語と一線を画している特徴的な機能の一つにテンプレートという機構があります。
……と、書くと一部のクラスタから猛烈な抗議のメールを受け取ることになるので気をつけましょう。彼らはHaskellという一般の人には理解できない言語を日常的に使い、その特性にあるように完全に純粋で、自分たちを第一級オブジェクトとして扱う為、建設的な議論が困難です。
テンプレートの話に戻りましょう。
1 2 3 4 |
template <typename T> T x2(const T& t) { return t * 2; } |
受け取った値を倍にして返すだけの関数ですが、組み込み型のint, floatはもちろん、ユーザー定義の型であっても、適切に*(int)演算子が定義されていれば倍にして返してくれます。便利ですね。
一度コードを書くだけで、型毎に自動的に関数を生成してくれる為、非常に柔軟で楽チンですが、それでも万能ではありません。
特定の型の時だけ振る舞いを変えたい場合も出てきます。
例えば文字列に対して倍にするって何だ?みたいな話があるので、文字列型に対してx2が呼ばれた場合は、受け取った文字列を2回繰り返した文字列にして返すようにしてみましょう。
1 2 3 4 |
template<> std::string x2(const std::string& t) { return t + t; } |
std::stringを受け取った場合はこちらのx2が呼ばれます。
これをテンプレートの特殊化といいます。
この場合はx2()をstd::stringに対して特殊化しました。
1 2 3 4 5 6 7 8 9 |
int main() { int a = 3; std::cout << x2(a) << std::endl; float b = 4.0f; std::cout << x2(b) << std::endl; std::string c = "abc"; std::cout << x2(c) << std::endl; return 0; } |
1 2 3 4 |
[出力] 6 8 abcabc |
まとめ
- 一部の型向けにテンプレート関数(or クラス)の実装を変えたい時はテンプレートの特殊化を行えばいい
- Haskellerには注意
- D言語界隈にも注意