C または C++ では、関数宣言と関数シグネチャの違いは何ですか?
関数宣言についてはある程度知っていますが、関数シグネチャはまったく新しいものです。関数シグネチャの概念を持つことのポイントは何ですか? 実際に使用される2つの概念は何ですか?
ありがとう!
C または C++ では、関数宣言と関数シグネチャの違いは何ですか?
関数宣言についてはある程度知っていますが、関数シグネチャはまったく新しいものです。関数シグネチャの概念を持つことのポイントは何ですか? 実際に使用される2つの概念は何ですか?
ありがとう!
関数宣言は、関数のプロトタイプです (または、その時点でコンパイラーによってプロトタイプが認識されていない場合は、関数定義から取得できます)。これには、戻り値の型、関数の名前、およびパラメーターの型が含まれます (オプションで C)。
関数シグネチャは、コンパイラがオーバーロード解決を実行するために使用する関数宣言の一部です。複数の関数が同じ名前を持つ (オーバーロードされている) 可能性があるため、コンパイラは、関数呼び出しが特定の名前を持ついくつかの可能な関数のどれに解決されるかを判断する方法を必要とします。署名は、そのオーバーロードの解決でコンパイラが考慮するものです。具体的には、標準では「署名」を次のように定義しています。
オーバーロードの解決に参加する関数に関する情報: そのパラメーターの型と、関数がクラス メンバーの場合は、関数自体およびメンバー関数が宣言されているクラスの cv 修飾子 (存在する場合)。
戻り値の型は関数シグネチャの一部ではないことに注意してください。標準が脚注で述べているように、「オーバーロードの解決に関与しないため、関数シグネチャには戻り値の型は含まれません」。
この規格では、宣言と定義という 2 つの用語が定義されています。定義は暫定的な宣言です。ただし、C99 および C++03 標準では、定義が若干異なります。
C++0x ドラフトから:
付録 C
8.3.5変更: C++ では、空のパラメータ リストで宣言された関数は引数を取りません。C では、空のパラメーター リストは、関数の引数の数と型が不明であることを意味します。」
定義
1.3.11 署名
関数の名前とパラメーター型リスト (8.3.5)、およびそれがメンバーであるクラス、概念、概念マップ、または名前空間。関数または関数テンプレートがクラス メンバーである場合、そのシグネチャには、関数または関数テンプレート自体の cv 修飾子 (存在する場合) および ref 修飾子 (存在する場合) が追加で含まれます。制約付きメンバー (9.2) の署名には、そのテンプレート要件が含まれます。関数テンプレートの署名には、戻り値の型、テンプレート パラメーター リスト、およびテンプレート要件 (存在する場合) が追加で含まれます。関数テンプレートの特殊化の署名には、それが特殊化されているテンプレートの署名とそのテンプレート引数 (明示的に指定されているか推定されているかに関係なく) が含まれます。[ 注: 署名は、名前のマングリングとリンクの基礎として使用されます。 — 末尾の注 ]
関数のシグネチャには、関数の戻り値の型またはリンケージの型は含まれません。
OK、ウィキペディアは、戻り値の型が含まれていることに同意しません。ただし、関数呼び出しが署名と一致するかどうかを判断するときに、戻り値の型がコンパイラによって使用されないことはわかっています。この以前の StackOverflow の質問は一致しているように見えます: Is the return type part of function signature?
また、標準によると、最上位の const と引数の volatile は署名の一部ではないことに注意してください。しかし、一部のコンパイラはこれを誤解しています。
例えば
void f(const int, const char* const);
と同じ署名があります
void f(int, const char*);
関数宣言はプロトタイプです。関数シグネチャは、シグネチャを構成するために使用される戻り値の型とパラメーターを示します。このことを考慮:
int foo(int, int); /* 関数宣言 */ /* foo の実装 ** 関数シグネチャ */ int foo(int a, int b){ }
ここで、次のシナリオを考えてみましょう: プログラマーは、 の関数シグネチャは何かを尋ねられますfoo
。
int
int
、nameda
およびb
それぞれのデータ型です一方、関数プロトタイプは、C/C++ コンパイラで何を期待するかの手がかりとなり、署名がプロトタイプと一致しない場合、コンパイラは「関数宣言エラー」のコンテキストに沿ってエラーを出力します。 「プロトタイプの不一致」。