関数型が異なっていても問題ありませんが、関数型の一部であるものとそうでないものを知る必要があります。あなたの場合、const
パラメータのforは重要ではないので、関数の型は同じですが、宣言は定義とは異なるように見えます。
あなたの場合それは
8.3.5関数[dcl.fct]
5単一の名前は、単一のスコープ内の複数の異なる機能に使用できます。これは関数のオーバーロードです(13節)。関数のすべての宣言は、戻り型とパラメータ型リストの両方で正確に一致する必要があります。関数のタイプは、次のルールを使用して決定されます。各パラメーターのタイプ(関数パラメーターパックを含む)は、独自のdecl-specifier-seqおよびdeclaratorから決定されます。各パラメータのタイプを決定した後、「Tの配列」または「Tを返す関数」タイプのパラメータは、それぞれ「Tへのポインタ」または「Tを返す関数へのポインタ」に調整されます。パラメーター型のリストを作成した後、パラメーター型を変更する最上位のcv修飾子は、関数型を形成するときに削除されます。結果として得られる変換されたパラメータータイプのリスト、および省略記号または関数パラメーターパックの有無は、関数のパラメータータイプリストです。[注:この変換は、パラメーターのタイプには影響しません。例えば、int(*)(const int p, decltype(p)*)
とint(*)(int, const int*)
は同じタイプです。—エンドノート]
どうやら説明が必要なので、ここで説明します。この場合の重要な文は次のとおりです。パラメーター型のリストを作成した後、パラメーター型を変更する最上位のcv修飾子は、関数型を形成するときに削除されます。
これは、すべての最上位のcv修飾子が削除されることを意味します。トップレベルの意味を説明するために、aが何をconst
指しているかを強調するために、違法な方法で型を記述します。
const int
= (const (int))
->これはトップレベルですconst
const int*
= ((const (int))*)
->トップレベルではなく、2番目のレベルにあります
const int* const
= (((const (int))*) const)
->2番目const
はトップレベルです
const int&
= ((const (int))&)
->トップレベルではありません
これにより、関数の型に関する誤解が解消されることを願っています。
他の質問については、宣言と定義を同一にしておくことをお勧めします。これは、人々を混乱させる可能性があるためです(この質問で証明されているように;)。
あなたが与えたその例のためにmain
:
int main( const int argc, const char* const argv[] )
は、上記の標準からの引用によれば、次のようになります。
int main( int argc, const char* const* argv )
したがって、追加されconst
たforは、削除さargv
れるトップレベルconst
にはなりません。したがって、これは、の形式が正しくない関数型でmain
あり、次のことを期待しています。
int main( int argc, char** argv )
パラメータ名を省略することについての最後の質問:私にとって、それらは関数のドキュメントの一部であるため、私はそれをしません。それらは、関数の意図とセマンティクスを伝達します(賢明に選択した場合)。