名稱空間
變體
操作

return 語句

來自 cppreference.com
< cpp‎ | 語言
 
 
C++ 語言
 
 

終止當前函式並將指定值(如果有)返回給呼叫者。

目錄

[編輯] 語法

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 起)
屬性 - (C++11 起) 任意數量的屬性序列
表示式 - 表示式,可轉換為函式返回型別
braced-init-list - 用花括號括起來的初始化列表

[編輯] 解釋

1) 評估 expression,終止當前函式並將 expression 的結果(經過向函式返回型別的隱式轉換後)返回給呼叫者。expression 在返回型別為 (可能是 cv-qualified) void 的函式中是可選的,在建構函式和解構函式中則不允許。
2) 使用複製列表初始化來建構函式的返回值。
3,4) 在協程中,對於最終掛起點必須使用關鍵字 co_return 而不是 return(詳情請參閱協程)。

在函式呼叫結果的複製初始化和 expression 結束時所有臨時物件的銷燬之間有一個序列點

(C++11 前)

函式呼叫結果的複製初始化先於 expression 結束時所有臨時物件的銷燬進行,而臨時物件的銷燬又先於包含 return 語句的塊的區域性變數的銷燬進行。

(C++11 起)

如果函式的返回型別是引用型別,並且 return 語句 (1,2) 將返回的引用繫結到臨時表示式的結果,則程式格式錯誤。

(C++26 起)

如果控制流到達以下函式的末尾

  • 返回型別為 (可能是 cv-qualified) void 的函式,
  • 建構函式,
  • 解構函式,或者
  • 返回型別為 (可能是 cv-qualified) void函式 try

而沒有遇到 return 語句,則執行 return;

如果控制流到達main 函式的末尾,則執行 return 0;

除了 main 函式和特定的協程(C++20 起) 之外,值返回函式在沒有 return 語句的情況下執行到末尾是未定義行為。

在返回 (可能是 cv-qualified) void 的函式中,如果表示式型別是 (可能是 cv-qualified) void,則可以使用帶 expression 的 return 語句。

如果函式的返回型別指定為佔位符型別,它將從返回值推導

(C++14 起)

[編輯] 注意

按值返回可能涉及臨時物件的構造和複製/移動,除非使用複製省略。具體來說,複製/移動的條件如下:

從區域性變數和引數的自動移動

如果 expression 是一個(可能是帶括號的)識別符號表示式,它命名了一個具有自動儲存持續時間且型別為:

  • 非 volatile 物件型別
(C++11 起)
  • 或非 volatile 右值引用物件型別
(C++20 起)

且該變數宣告在

  • 最內層包圍函式或 lambda 表示式的函式體中
  • 或作為其引數

的變數,則 expression 是*可移動的*。

(C++11 起)

如果 expression 是可移動的,用於選擇建構函式以初始化返回值或,對於 co_return,用於選擇 promise.return_value() 的過載(C++20 起)過載決議將執行*兩次*:

  • 首先,就好像 expression 是一個右值表示式(因此它可能選擇移動建構函式),並且
  • 如果第一次過載決議失敗
(C++11 起)
(直至 C++23)
  • 或者成功了,但沒有選擇移動建構函式(形式上,所選建構函式的第一個引數不是對 expression 的(可能是 cv-qualified)型別的右值引用)
(C++11 起)
(C++20 前)
  • 則按照通常的方式執行過載決議,將 expression 視為左值(因此它可能選擇複製建構函式)。
(C++11 起)
(直至 C++23)

如果 expression 是可移動的,則將其視為 xvalue(因此過載決議可能選擇移動建構函式)。

(C++23 起)

保證的複製省略

如果 expression 是一個純右值,則結果物件由該表示式直接初始化。當型別匹配時,這不涉及複製或移動建構函式(參閱複製省略)。

(C++17 起)
功能測試宏 標準 特性
__cpp_implicit_move 202207L (C++23) 隱式移動的簡化

[編輯] 關鍵字

return, co_return

[編輯] 示例

#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++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
CWG 1541 C++98 如果返回型別是 cv-qualified void,則 expression 不能省略 它可以省略
CWG 1579 C++11 不允許透過轉換移動建構函式返回 允許轉換移動
建構函式查詢
CWG 1885 C++98 自動變數銷燬的順序不明確 添加了排序規則

[編輯] 另請參閱

C 文件 關於 return 語句