A mere hateblo

単なるはてブロです。

関数(メソッド)の再定義と多重定義

昨日ごりごりRuby書いているときに他の言語の感覚のままでハマったこと - 日々の御伽噺を読んで、C++ではどうかと思い確認した。

int foo(int a, int b)
{
  return 1;
}

int foo(int a, int b, int c = 0)
{
  return 0;
}

int main()
{
  return foo(1, 2);
}
% g++ -Wall -Wextra -O0 -g func_overload.cc
func_overload.cc:1: warning: unused parameter ‘a’
func_overload.cc:1: warning: unused parameter ‘b’
func_overload.cc:6: warning: unused parameter ‘a’
func_overload.cc:6: warning: unused parameter ‘b’
func_overload.cc:6: warning: unused parameter ‘c’
func_overload.cc: In function ‘int main()’:
func_overload.cc:13: error: call of overloaded ‘foo(int, int)’ is ambiguous
func_overload.cc:1: note: candidates are: int foo(int, int)
func_overload.cc:6: note:                 int foo(int, int, int)

ということで、曖昧な呼び出しとしてコンパイルエラーになった。ただし、呼び出し側の引数を3つにするか、上記二つ目のfoo()で引数からデフォルト値を取り除けばコンパイルは通る(それでいいのかどうかは状況による)。

同じ関数(メソッド)名を再度定義した場合、Rubyでは再定義(オーバーライド)、C#では多重定義(オーバーロード)となるようだ。C++では関数の再定義は行えないが、上記のように多重定義は行える。ただし呼び出し方によって曖昧なものとして扱われコンパイルに失敗する、ということか。