14.1 オーバーロード
14.2 多重定義関数の識別
/* 仮引数バリエーションで区別 */
int smp();
int smp(int a);
int smp(int a, int b);
int smp(double a);
int smp(double a, double b);
int smp(int a, double b);
int smp(double a, int b);
いずれも仮引数の型または個数または並び順が違っているので、
関数多重定義として正しいものです。
/* 戻り値の違いでは区別できない */
多重定義関数は呼び出しスタイルを使って区別します。
戻り値の型では区別しません。
int smp(int a);
void smp(int a);
double smp(int a);
また仮引数名が違うことでは区別できません。
仮引数名は関数プロトタイプの必須要素ではないので、これは当然のことです。
int smp(int a);
int smp(int data);
/* constやvolatileの有無による区別 */
データ型そのものにconstやvolatileを付けたものも区別されません。
void smp(int a);
void smp(const int a);
ただし、ポインタや参照は、constやvolatileの有無が区別の対象になります。
注意が必要です。
以下、全て区別できる
void smp(int *a)
void smp(const int *a)
void smp(volatile int *a)
void smp(int &a)
void smp(const int &a)
void smp(volatile int &a)
void smp(char *a)
void smp(const char *a)
void smp(volatile char *a)
/* 参照を用いたときの区別 */
void smp(int a)
void smp(int &a)
を呼び出すときは、
int dt;
smp(dt); // (1)の関数か(2)の関数か判定不能
/* ポインタを用いたときの区別 */
型と型へのポインタ(aと*aの関係)のときの初期化子は区別できます。
したがって
void smp(int a)
void smp(int *a)
は区別可能で、正しい多重定義です。
また当然ですが、
void smp(int *a)
void smp(int &a)
も多重定義です。
また、ポインタ表現と、それと同等な配列表現は、
同一の呼び出しスタイルになるので区別できません。
void smp(char s[])
void smp(char *s)
14.3 引数の照合と変換
(1)引数の型と個数が完全に一致
(2)標準変換(変換または昇格)による一致
(3)利用者定義変換による一致
(4)省略①(...)がある