スポンサーリンク

浮動小数点以外の値が入力されたら浮動小数点が入力されたことにするテンプレート関数

目的

以下のような関数があるとする。

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();
}

正直、エラーの読みづらさをいうならテンプレートを使った時点で大変なことになるので説得力は微妙。

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: