return
statement
终止当前函数并将指定值(如果有)返回给调用者。
目录 |
语法
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 | - | (since C++11) 任意数量的 属性 序列 |
| expression | - | 可转换为函数返回类型的 表达式 |
| braced-init-list | - | 花括号初始化列表 |
说明
表达式 或 花括号初始化列表 (C++11 起) (若存在)被称为 return 语句的 操作数 。
|
函数调用结果的复制初始化与 表达式 末尾所有临时对象的销毁之间存在一个 顺序点 。 |
(C++11 前) |
|
函数调用结果的复制初始化 先序于 表达式 末尾所有临时对象的销毁,而后者又 先序于 包围 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 语句。
|
若函数的返回类型被指定为 占位类型 ,则将从返回值 推导 其类型。若使用 decltype ( auto ) ,类型推导会将可视为 实体 的 表达式 作为 实体 处理。 |
(since C++14) |
注释
以值返回可能涉及临时对象的构造和复制/移动,除非使用了 复制消除 。具体而言,复制/移动的条件如下:
自动从局部变量和参数移动当 表达式 是(可能带括号的) 标识符表达式 ,且命名的自动存储期变量类型满足以下条件时,该表达式具有 移动资格 :
|
(since C++11) |
|
(since C++20) |
|
且该变量声明于
|
(since C++11) |
|
若 表达式 具有移动资格,则进行 重载决议 以选择用于初始化返回值的构造函数 (或对于 co_return ,选择 promise. return_value ( ) 的重载) (since C++20) 时会执行 两次 :
|
(since C++11)
(until C++23) |
|
(since C++11)
(until C++20) |
|
(since C++11)
(until C++23) |
|
若 表达式 具有移动资格,则将其视为亡值(因此重载决议可能选择 移动构造函数 )。 |
(since C++23) |
保证的拷贝消除若 表达式 是纯右值,则结果对象直接由该表达式初始化。当类型匹配时,该过程不涉及拷贝或移动构造函数(参见 拷贝消除 )。 |
(since 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"; } // 隐式返回 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) 是 void 表达式 } int main() { fa(1); // 打印参数后返回 fa(2); // 当 i == 2 时不执行任何操作,直接返回 int i = fb(5); // 返回 4 i = fb(i); // 打印参数后返回 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; // 正确:隐式移动 } MoveOnly move_11(MoveOnly&& arg) { return arg; // C++20 起正确:隐式移动 } MoveOnly&& move_23(MoveOnly&& arg) { return arg; // C++23 起正确:隐式移动 }
输出:
fa(1) fb(4) i = 2 fc(~).second = 7 fa(10)
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 适用范围 | 发布时行为 | 正确行为 |
|---|---|---|---|
| CWG 1541 | C++98 | 若返回类型为 cv 限定 void 则不能省略 expression | 允许省略 |
| CWG 1579 | C++11 | 不允许通过转换移动构造函数返回 |
启用转换移动
构造函数查找 |
| CWG 1885 | C++98 | 未明确自动变量析构的顺序规则 | 添加顺序规则 |
参见
|
C 文档
关于
return
语句
|