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 | - | expression,可转换为函数返回类型 |
braced-init-list | - | 花括号包围的初始化器列表 |
[编辑] 解释
在函数调用的结果的复制初始化与在 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 起) 两次
|
(自 C++11 起) (直到 C++23) |
|
(自 C++11 起) (直到 C++20) |
|
(自 C++11 起) (直到 C++23) |
如果 expression 是可移动的,则将其视为 xvalue(因此重载决议可能选择移动构造函数)。 |
(自 C++23 起) |
保证复制省略如果 expression 是纯右值,则结果对象由该表达式直接初始化。当类型匹配时,这不涉及复制或移动构造函数(参见复制省略)。 |
(自 C++17 起) |
特性测试宏 | 值 | Std | 特性 |
---|---|---|---|
__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 | 自动变量的销毁顺序不明确 | 添加了排序规则 |
[编辑] 参见
C 文档 关于
return 语句 |