LoginSignup
11
8

More than 5 years have passed since last update.

引数の型が同じで返却値の型が違う関数

Posted at

C++ では仮引数の型が全て同じで返却値だけ型が違うような関数をオーバーロードすることは出来ません。 以下のようなオーバーロードを試みるとエラーになることが確認できると思います。

constexpr int one(void) {
  return 1;
}

constexpr char one(void) {
  return '1';
}

どうしても返却値だけ型が違う関数を定義したいのならばテンプレート (特殊化) を使う方法があります。

template<class T> constexpr T one(void);

template<> constexpr int one(void) {
  return 1;
}

template<> constexpr char one(void) {
  return '1';
}

ところが、 C++ の関数テンプレートの型推論は引数の型を基にしておこなうので、引数の型が同じ (今回の例では引数を受け取らない) 関数テンプレートでは推論できません。 以下のように、呼出すときに型を陽に指定する必要があります。

#include <iostream>

int main(void) {
  constexpr int a=one<int>();
  constexpr char b=one<char>();
  std::cout << a << b <<std::endl;
  return 0;
}

関数呼出しの際にどうにかして型を書かずに済ます方法はないかと考えたとき、型変換演算子を活用するという方法を思い付きました。

class one {
public:
  constexpr one(void) {}
  template<class T> constexpr operator T(void);
};

template<> constexpr one::operator int(void) {
    return 1;
}

template<> constexpr one::operator char(void) {
  return '1';
}

#include <iostream>

int main(void) {
  constexpr int a=one();
  constexpr char b=one();
  std::cout << a << b <<std::endl;
  return 0;
}

型変換の時点で実際の処理を発生させるので、副作用を(ともな)う関数では注意深く扱う必要がありますが、そうでない場合には有用な場面もあるのではないでしょうか。

11
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
8