1. ホーム
  2. c++

戻り値の型は関数シグネチャの一部ですか?

2023-10-10 10:32:24

質問

C++では、戻り値の型は関数シグネチャの一部とみなされますか? また、戻り値の型を変更しただけのオーバーロードは許されません。

どのように解決するのですか?

通常の関数では、シグネチャに戻り値の型が含まれません。

( ノート : 私はこの回答を書き直したので、以下のコメントはこのリビジョンには適用されません - 詳細は編集履歴をご覧ください)。

はじめに

しかし、Standardにおける関数と関数宣言の問題は複雑です。考慮しなければならない2つの層があります。

  • 宣言
  • エンティティ

いわゆる 関数宣言 は、関数エンティティまたはテンプレートエンティティを宣言することができます。関数実体が宣言されている場合、関数テンプレートの明示的な特殊化(全ての引数が指定されている)か、通常の関数の宣言のどちらかを行わなければなりません。テンプレート実体が宣言されている場合は、一次関数テンプレート、または、いくつかの引数が指定されていない明示的な特殊化を宣言していることになります。(これは、"オブジェクト宣言"とオブジェクトやリファレンスの関係に非常に似ている。前者はオブジェクトと参照のどちらかを宣言することができます。そのため オブジェクト宣言 は必ずしもオブジェクトを宣言しているとは限りません!)。

標準規格では、関数のシグネチャは次のようなものを含むと定義されています。 1.3.10 :

引数の型,関数がクラスメンバの場合,関数自身とメンバ関数が宣言されているクラスに対する cv- 修飾子(もしあれば).関数テンプレート特化型のシグネチャには,そのテンプレート引数の型が含まれます.(14.5.5.1)

この定義では戻り値の型が欠落していますが、これは が指摘するように、関数テンプレートの特殊化 (すなわち、テンプレートの特殊化である関数を宣言する関数宣言) のシグネチャの一部であります。 14.5.5.1 (で指摘されています(最近の C++0x 作業文書では、戻り値の型に言及するためにすでに修正されています)。 1.3.10 にも言及するように修正されました)。

関数テンプレートの特殊化の署名は、関数テンプレートの署名と実際のテンプレート引数(明示的に指定されているか、推論されているか)から構成されます。

関数テンプレートのシグネチャは、その関数のシグネチャ、戻り値の型、テンプレート引数のリストで構成されます。

では、シグネチャには一体何が含まれているのでしょうか?

ということで、シグネチャについて質問すると 関数 のシグネチャについて質問された場合、2つの答えを出さなければなりません。

  • 関数テンプレートの特殊化である関数の場合、シグネチャには戻り値の型が含まれます。
  • 特殊化されていない関数では、戻り値の型はシグネチャの一部ではありません。

しかしながら、どのような場合でも戻り値の型は、そのことに注意してください。 は関数の型の重要な部分であることに注意してください。つまり、次のようなものは無効です。

void f();
int (*pf)() = &f; // different types!

戻り値の型が異なるだけで、オーバーロードが無効となるのはどのような場合ですか?

現在、主要なコンパイラは以下のコードを拒否します。

int f();
double f(); // invalid

しかし、次のコードを受け入れる。

template<typename T> int f();
template<typename T> double f(); // invalid?

しかし 規格では、戻り値の型が異なるだけの関数宣言は禁止されています。 (オーバーロードが有効な場合とそうでない場合を定義する場合) を禁止しています。しかし、quot;difers only by return type"が何を意味するのか正確には定義されていません。


標準的な段落の参照です。

  • 関数宣言はいつオーバーロードできるのか。 13.1
  • 関数宣言とは何か。 7/27/5
  • 関数テンプレート/特殊化のシグネチャは何ですか。 14.5.5.1

参考までに、最新の C++0x ドラフト n3000 では、"signature" について以下のように記述されています。 1.3.11 での &qu;signature" について述べているもので、異なるタイプのエンティティをより完全に網羅しています。

<ブロッククオート

関数の名前とパラメータ型リスト (8.3.5)、そして関数が所属するクラスまたは名前空間。関数や関数テンプレートがクラスのメンバである場合、その署名はさらに関数や関数テンプレート自体の cv-qualifiers (もしあれば) と ref-qualifier (もしあれば) を含んでいます。関数テンプレートのシグネチャには,さらにその戻り値の型とテンプレートパラメータリストが含まれます.関数テンプレートの特殊化の署名は、それが特殊化されたテンプレートの署名と、そのテンプレート引数(明示的に指定されたか推論されたかにかかわらず)を含みます。[注意:シグネチャは名前のマングリングとリンクのための基礎として使われます。- エンドノート ]。