web-dev-qa-db-ja.com

コンストラクタにreturnステートメントを書くとどうなりますか?

コンストラクタにreturnステートメントを書くとどうなりますか?標準に準拠していますか?

struct A
{ 
     A() { return; } 
};

上記のコードは、 ideone でエラーなくコンパイルできます。しかし、次のコードはそうではありません:

struct A
{ 
   A() { return 100; } 
};

ideone でこのエラーが発生します:

エラー:コンストラクタから値を返す

私は、コンストラクタから値を返すことはまったく意味をなさないことを理解しています。なぜなら、明示的に戻り値の型を言及しておらず、結局、戻り値を保存できないからです。しかし、私は知りたいです:

  • C++標準のどのステートメントが最初の例を許可しますが、2番目の例を禁止しますか? explicitステートメントはありますか?
  • 最初の例の戻り値typevoid
  • implicit戻り型はありますか?
44
Nawaz

はい、コンストラクターでreturnステートメントを使用することは完全に標準です。

コンストラクターは、値を返さない関数です。値を返さない関数のファミリーは、void関数、コンストラクター、およびデストラクターで構成されます。 C++標準の6.6.3/2に記載されています。同じ6.6.3/2は、値を返さない関数でreturnを引数とともに使用することは違法であると述べています。

6.6.3 returnステートメント

2式のないreturnステートメントは、値を返さない関数、つまり戻り値の型がvoidの関数、コンストラクター(12.1)、またはデストラクター(12.4)でのみ使用できます。非void型の式を持つreturnステートメントは、値を返す関数でのみ使用できます。式の値は、関数の呼び出し元に返されます。

さらに、12.1/12は

12.1コンストラクター

12戻り値の型(voidでさえない)はコンストラクタに指定されません。コンストラクターの本体のreturnステートメントは、戻り値を指定しません。

ところで、C++では、returnの引数の型がreturnである限り、void関数の引数でvoidを使用することができます。

void foo() {
  return (void) 0; // Legal in C++ (but not in C)
}

ただし、コンストラクターはvoid関数ではないため、コンストラクターでは許可されません。

コンストラクターでのreturnの使用に関連する1つの比較的曖昧な制限もあります:コンストラクターのfunction-try-blockでreturnを使用することは違法です(他の関数ではOK)

15.3例外の処理

15 returnステートメントがコンストラクターのfunction-try-blockのハンドラーにある場合、プログラムの形式は正しくありません。

74
AnT

おそらく、コンストラクターで型なしの戻り値を持つという概念は、コンストラクター関数の終了を制御することです。

struct A
{ 
// more definitions     
A() 
{ 
if( !goodToGoOn)  
 return;
// the rest of the stuffs go here
} 
};
5
Shamim Hafiz