return 文
現在の関数を終了し、指定された値(もしあれば)を呼び出し元に返します。
目次 |
[編集] 構文
attr (オプション) return expression (オプション) ; |
(1) | ||||||||
attr (オプション) return braced-init-list ; |
(2) | (C++11以降) | |||||||
attr (オプション) co_return expression (オプション) ; |
(3) | (C++20以降) | |||||||
attr (オプション) co_return braced-init-list ; |
(4) | (C++20以降) | |||||||
| attr | - | (C++11以降) 任意の数の属性のシーケンス |
| 式 | - | 式、関数戻り値型に変換可能 |
| 波括弧初期化子リスト | - | 波括弧で囲まれた初期化子リスト |
[編集] 説明
|
関数呼び出しの結果のコピー初期化と、expression の末尾にあるすべての一時オブジェクトの破棄との間にシーケンスポイントが存在します。 |
(C++11まで) |
|
関数呼び出しの結果のコピー初期化は、expression の末尾にあるすべての一時オブジェクトの破棄の前に順序付けされ、それはさらに return 文を囲むブロックのローカル変数の破棄の前に順序付けされます。 |
(C++11以降) |
|
関数の戻り値型が参照型であり、return 文 (1,2) が返された参照を一時式の結果にバインドする場合、プログラムは不正です。 |
(C++26以降) |
制御が
- 戻り値の型が(cv修飾されている可能性のある)void の関数の末尾、
- コンストラクタの末尾、
- デストラクタの末尾、または
- 戻り値の型が(cv修飾されている可能性のある)void の関数の関数 try ブロックの末尾
に return 文に遭遇せずに到達した場合、return; が実行されます。
制御がmain 関数の末尾に到達した場合、return 0; が実行されます。
main 関数と特定のコルーチン(C++20以降)を除き、return 文なしで値を返す関数の末尾にフローオフすることは未定義動作です。
戻り値の型が(cv修飾されている可能性のある)void の関数では、式の型が(cv修飾されている可能性のある)void であれば、expression を伴う return 文を使用できます。
| (C++14以降) |
[編集] 注釈
コピーエリジョンが使用されない限り、値による返却は一時オブジェクトの構築とコピー/ムーブを伴う場合があります。具体的には、コピー/ムーブの条件は次のとおりです。
ローカル変数とパラメーターからの自動ムーブexpression は、自動記憶域期間を持つ変数を指定する(括弧で囲まれている可能性のある)識別子式であり、その型が
|
(C++11以降) |
|
(C++20以降) |
|
であり、かつその変数が
最も内側の囲む関数またはラムダ式で宣言されている場合に、ムーブ可能です。 |
(C++11以降) |
|
expression がムーブ可能な場合、返される値の初期化に使用するコンストラクタを選択するためのオーバーロード解決または、co_return の場合、promise.return_value() のオーバーロードを選択するため(C++20以降)は2回実行されます。
|
(C++11以降) (C++23まで) |
|
(C++11以降) (C++20まで) |
|
(C++11以降) (C++23まで) |
|
expression がムーブ可能な場合、xvalue として扱われます(したがって、オーバーロード解決によりムーブコンストラクタが選択される場合があります)。 |
(C++23から) |
保証されたコピーエリジョンexpression が prvalue の場合、結果オブジェクトはその式によって直接初期化されます。型が一致する場合、これはコピーまたはムーブコンストラクタを伴いません(コピーエリジョンを参照)。 |
(C++17以降) |
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__cpp_implicit_move |
202207L |
(C++23) | よりシンプルな暗黙的なムーブ |
[編集] キーワード
[編集] 例
#include <iostream> #include <string> #include <utility> void fa(int i) { if (i == 2) return; std::cout << "fa("<< i << ")\n"; } // implied return; int fb(int i) { if (i > 4) return 4; std::cout << "fb(" << i << ")\n"; return 2; } std::pair<std::string, int> fc(const char* p, int x) { return {p, x}; } void fd() { return fa(10); // fa(10) is a void expression } int main() { fa(1); // prints its argument, then returns fa(2); // does nothing when i == 2, just returns int i = fb(5); // returns 4 i = fb(i); // prints its argument, returns 2 std::cout << "i = " << i << '\n' << "fc(~).second = " << fc("Hello", 7).second << '\n'; fd(); } struct MoveOnly { MoveOnly() = default; MoveOnly(MoveOnly&&) = default; }; MoveOnly move_11(MoveOnly arg) { return arg; // OK. implicit move } MoveOnly move_11(MoveOnly&& arg) { return arg; // OK since C++20. implicit move } MoveOnly&& move_23(MoveOnly&& arg) { return arg; // OK since C++23. implicit move }
出力
fa(1) fb(4) i = 2 fc(~).second = 7 fa(10)
[編集] 欠陥報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| CWG 1541 | C++98 | 戻り値の型が cv 修飾された void の場合、expression は省略できませんでした。 | 省略可能です。 |
| CWG 1579 | C++11 | 変換ムーブコンストラクタによる返却は許可されていませんでした。 | 変換ムーブ コンストラクタ検索が有効になりました。 |
| CWG 1885 | C++98 | 自動変数の破棄の順序付けが明示的ではありませんでした。 | 順序付けルールが追加されました。 |
[編集] 関連項目
return 文のCドキュメント |