引き数が指定されていない多重定義された関数名 f を使用する場合、
その名前は、関数、関数を指すポインター、メンバー関数を指すポインター、
または関数テンプレートの特殊化を参照することができます。
引き数が指定されなかったので、コンパイラーは、
関数呼び出しまたは演算子の使用に対して実行するのと同じ方法では、
多重定義解決を実行することができません。
その代わりに、コンパイラーは、f を使用した場所に応じて、
以下の式のうちの 1 つの式の型に一致する、最良の実行可能関数を選択しようと試みます。
ユーザーが f を使用したときに、コンパイラーが非メンバー関数または静的メンバー 関数の宣言を選択した場合、コンパイラーは、宣言を型「関数へのポインター」または「関数への参照」の式に突き合わせました。 コンパイラーが非静的メンバー関数の宣言を選択した場合、コンパイラーは、 その宣言を型「メンバーを指すポインター関数」の式に突き合わせました。 次の例は、このことを示しています。
struct X { int f(int) { return 0; } static int f(char) { return 0; } }; int main() { int (X::*a)(int) = &X::f; // int (*b)(int) = &X::f; }
コンパイラーは、関数ポインター b の初期化を許可しません。 型 int(int) の非メンバー関数または静的関数は、宣言されていません。
f がテンプレート関数の場合、コンパイラーは、テンプレート引き数推論を実行して、 どのテンプレート関数を使用するかを決めます。 うまくいけば、その関数を実行可能関数のリストに追加します。 このセットに、非テンプレート関数を含めて、複数の関数がある場合、 コンパイラーは、セットからすべてのテンプレート関数を除去し、非テンプレート関数を選択します。このセットにテンプレート関数だけがある場合、コンパイラーは、 最も特殊化されたテンプレート関数を選択します。次の例は、このことを示しています。
template<class T> int f(T) { return 0; } template<> int f(int) { return 0; } int f(int) { return 0; } int main() { int (*a)(int) = f; a(1); }
関数呼び出し a(1) は、int f(int) を呼び出します。
関連参照