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 起) | |||||||
属性 | - | (C++11 起) 任意数量的属性序列 |
表达式 | - | 表达式,可转换为函数返回类型 |
braced-init-list | - | 用花括号括起来的初始化列表 |
[编辑] 解释
在函数调用结果的复制初始化和 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 是一个(可能是带括号的)标识符表达式,它命名了一个具有自动存储持续时间且类型为:
|
(C++11 起) |
|
(C++20 起) |
且该变量声明在
的变量,则 expression 是*可移动的*。 |
(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 起) |
功能测试宏 | 值 | 标准 | 特性 |
---|---|---|---|
__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++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
CWG 1541 | C++98 | 如果返回类型是 cv-qualified void,则 expression 不能省略 | 它可以省略 |
CWG 1579 | C++11 | 不允许通过转换移动构造函数返回 | 允许转换移动 构造函数查找 |
CWG 1885 | C++98 | 自动变量销毁的顺序不明确 | 添加了排序规则 |
[编辑] 另请参阅
C 文档 关于
return 语句 |