14

Forward declaration実際のタイプを実装ファイルまで定義することを延期することができます。これは、前方宣言された型へのポインタまたは参照のためのヘッダーで許可されます。返品タイプを定義する必要がありますか?

I have been toldこと:

値で返すと型定義を必要としません。前方宣言で十分です

誰かがこれを実際の見積もりで確認または拒否できますか?私はこれが合法ではないという印象を受けました。

+8

は、あなたは正確に、合法ではないと思われるものをクリアすることができますか?同様に、実際のコードサンプルは違法だと思いますか? – Yakk

+1

これは関数宣言に適用され、定義には適用されません。そして、いいえ、それは標準からの引用ではありません。 – juanchopanza

+4

おそらく、 "値で返すことは、**関数を宣言するときに型定義**を必要としません。"という前向き宣言で十分です。 "関数を定義するときと呼び出すときに定義が必要です。ところで、これはパラメータにも当てはまります。 –

答えて

25

値を返すことは、型定義を必要としません。前方宣言で十分です。

値で返される関数を宣言する場合、型定義は必要ありません。

struct S; 
S foo(); 
struct S {}; 
int main() { 
    foo(); 
} 
S foo() {} 

値で返される関数を定義または呼び出すには、型定義が必要です。標準草案[basic.def.odr]:クラスが完全であることをクラス型を必要とするように使用されている場合

5クラスのいずれか1つだけを定義は翻訳単位で必要とされます。 [例:... [snip] ... [注:宣言と式の規則は、どのようなコンテキストでクラス型が必要かを記述します。場合クラス型Tは、完全でなければならない:

  • タイプTの戻り型や引数型を持つ[省略]
  • 5.9関数が定義され([basic.def])または([exprを呼ばれ.call])、または
  • [省略]

不完全戻り型を持つ関数の宣言は、暗黙的に、リスト内のルールのいずれかによって禁止されていないのおかげで許可されます。

ルールは、後で標準で再文言され、それが(おかげでこのルールを指摘し@cpplearnerするために)例外[dcl.fct]によって緩和されます。

11種類は、お返しにまたは定義されてはなりませんパラメータ型。関数定義のパラメータまたは戻り型の型は、関数が削除されない限り([dcl.fct.def.delete])、関数定義の文脈では不完全(おそらくCV修飾された)クラス型であってはならない。


悪い形成デモ:

struct S; 
S foo(){} // oops 
struct S {}; 

別の病気に形成されたデモ:

struct S; 
S foo(); 
int main() { 
    foo(); // oops 
} 
struct S {}; 
S foo() {} 
+6

Upvotedこれは正確にOPが探していた標準の確認であるようです。 –

+0

右。コンパイラの設計の観点から考えると、完璧な意味があります。コンパイラがサイズや配置を知る必要がある場合は、型を完全にする必要があります。これらは式のコード生成や関数の戻り構造の設定に関係します。しかし、それらはもちろん、生成されたコードには現れず、コンパイラの内部構造を更新するだけの前方宣言については関係ありません。 – wchargin

関連する問題