どんな状況にも適していませんが、テンプレートは「コンパイル時のダックタイピング」を提供できます。
2 つのベクトル型があるとします。
struct Vec3A {
float x, y, z;
};
struct Vec3B {
float p[3];
};
コンポーネントを取得する方法の実装を非表示にする関数テンプレートを定義できます。
template<class T> float get_x(const T&);
template<class T> float get_y(const T&);
template<class T> float get_z(const T&);
template<> float get_x<Vec3A>(const Vec3A& v) { return v.x; }
// ...
template<> float get_x<Vec3B>(const Vec3B& v) { return v.p[0]; }
// ...
このようなヘルパーを使用すると、両方で機能する汎用関数を記述できるようになりました。
template<class T> float length(const T& t) {
return std::sqrt(std::pow(get_x(t), 2),
std::pow(get_y(t), 2),
std::pow(get_z(t), 2));
}
length()
パフォーマンスやその他の理由でユーティリティを特殊化することもできます。たとえば、特定のベクトルに長さを提供するメンバー関数が既にある場合などです。
template<> float length<Vec3C>(const Vec3C& v) {
return v.length();
}