以下のような関数があるとする。
float divide(const float a, const float b) { return a / b; }
諸事情によりテンプレート化を行ったとする。
template<typename T> auto divide(const T a,const T b) { return a/b; }
この時、整数が入力されたときにもまともな答えが出てほしい。
template<typename T> auto divide(const T a,const T b) { return a/b; } int main() { float a = divide(5.0,10.0); // a == 0.5 float b = divide(5,10); // b == 0.0 printf("%lf %lf", a,b); getchar(); }
こんなテンプレートを定義する
//入力が浮動小数点の時はそのまま返す //それ以外の時はfloatを返す template<typename T, bool isint>struct IsRealT; template<typename T>struct IsRealT<T, true> { using type = T; }; template<typename T>struct IsRealT<T, false> { using type = float; }; //入力が整数ならfloatを返す template<typename T> struct RealIfInt { using type = typename IsRealT<T, std::is_floating_point<T>::value>::type; };
内部でキャストする。なんで普通にdoubleでキャストしないでテンプレートで切り分けなんかするのか、そもそもこの関数自体doubleで受け取ればいいんじゃないのか、と思うのだが、型が違うと随所でwarningが出て読みづらくなるというのがある。
template<typename T> auto divide(const T a, const T b) { using realT = typename RealIfInt<T>::type; return static_cast<realT>(a) / static_cast<realT>(b); } int main() { auto a = divide(5.0, 10.0); // a == 0.5 auto b = divide(5, 10); // b == 0.5 printf("%lf %lf", a, b); getchar(); }
正直、エラーの読みづらさをいうならテンプレートを使った時点で大変なことになるので説得力は微妙。