C++
Compiler support
Freestanding and hosted
Language
Standard library
Standard library headers
Named requirements
Feature test macros
(C++20)
Language support library
Concepts library
(C++20)
Diagnostics library
Memory management library
Metaprogramming library
(C++11)
General utilities library
Containers library
Iterators library
Ranges library
(C++20)
Algorithms library
Strings library
Text processing library
Numerics library
Date and time library
Input/output library
Filesystem library
(C++17)
Concurrency support library
(C++11)
Execution control library
(C++26)
Technical specifications
Symbols index
External libraries
C++ language
General topics
Preprocessor
Comments
Keywords
Escape sequences
Flow control
Conditional execution statements
if
switch
Iteration statements (loops)
for
range-
for
(C++11)
while
do-while
Jump statements
continue
-
break
goto
-
return
Functions
Function declaration
Lambda function expression
inline
specifier
Dynamic exception specifications
(
until C++17*
)
noexcept
specifier
(C++11)
Exceptions
throw
-expression
try
block
catch
handler
Namespaces
Namespace declaration
Namespace aliases
Types
Fundamental types
Enumeration types
Function types
Class/struct types
Union types
Specifiers
const
/
volatile
decltype
(C++11)
auto
(C++11)
constexpr
(C++11)
consteval
(C++20)
constinit
(C++20)
Storage duration specifiers
Initialization
Default-initialization
Value-initialization
Zero-initialization
Copy-initialization
Direct-initialization
Aggregate initialization
List-initialization
(C++11)
Constant initialization
Reference initialization
Expressions
Value categories
Order of evaluation
Operators
Operator precedence
Alternative representations
Literals
Boolean
-
Integer
-
Floating-point
Character
-
String
-
nullptr
(C++11)
User-defined
(C++11)
Utilities
Attributes
(C++11)
Types
typedef
declaration
Type alias declaration
(C++11)
Casts
Implicit conversions
static_cast
const_cast
Explicit conversions
dynamic_cast
reinterpret_cast
Memory allocation
new
expression
delete
expression
Classes
Class declaration
Constructors
this
pointer
Access specifiers
friend
specifier
Class-specific function properties
Virtual function
override
specifier
(C++11)
final
specifier
(C++11)
explicit
(C++11)
static
Special member functions
Default constructor
Copy constructor
Move constructor
(C++11)
Copy assignment
Move assignment
(C++11)
Destructor
Templates
Class template
Function template
Template specialization
Parameter packs
(C++11)
Miscellaneous
Inline assembly
History of C++
Statements
Labels
label
:
statement
Expression statements
expression
;
Compound statements
{
statement
...
}
Selection statements
if
switch
Iteration statements
while
do while
for
range
for
(C++11)
Jump statements
break
continue
return
goto
Assertions
contract_assert
(C++26)
Declaration statements
declaration
;
Try blocks
try
block
Transactional memory
synchronized
,
atomic_commit
, etc
(TM TS)
终止当前函数并将指定值(如果有)返回给调用者。
目录
1
语法
2
解释
3
备注
3.1
自动从局部变量和参数移动
3.2
保证的复制消除
4
关键字
5
示例
6
缺陷报告
7
参阅
语法
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
-
花括号初始化列表
说明
1)
计算
表达式
的值,在将结果
隐式转换
为函数返回类型后,终止当前函数并将结果返回给调用方。对于返回类型为(可能带有cv限定符)
void
的函数,
表达式
是可选的;在构造函数和析构函数中则不允许使用
表达式
。
2)
使用
copy-list-initialization
来构造函数的返回值。
3,4)
在协程中,必须使用关键字
co_return
替代
return
作为最终挂起点(详见
协程
说明)。
表达式
或
花括号初始化列表
(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)
注释
以值返回可能涉及临时对象的构造和复制/移动,除非使用了
复制消除
。具体而言,复制/移动的条件如下:
自动从局部变量和参数移动
当
表达式
是(可能带括号的)
标识符表达式
,且命名的自动存储期变量类型满足以下条件时,该表达式具有
移动资格
:
非volatile对象类型
(since C++11)
或非volatile对象类型的右值引用
(since C++20)
且该变量声明于
最内层外层函数或lambda表达式的
函数体内
或作为参数声明
(since C++11)
若
表达式
具有移动资格,则进行
重载决议
以选择用于初始化返回值的构造函数
(或对于
co_return
,选择
promise.
return_value
(
)
的重载)
(since C++20)
时会执行
两次
:
首先将
表达式
视为右值表达式(因此可能选择
移动构造函数
),
若第一次重载决议失败
(since C++11)
(until C++23)
或决议成功但未选择
移动构造函数
(正式而言,所选构造函数的第一个参数不是
表达式
类型的(可能带cv限定符的)右值引用)
(since C++11)
(until C++20)
随后按常规方式进行重载决议,将
表达式
视为左值(因此可能选择
拷贝构造函数
)。
(since C++11)
(until C++23)
若
表达式
具有移动资格,则将其视为亡值(因此重载决议可能选择
移动构造函数
)。
(since C++23)
保证的拷贝消除
若
表达式
是纯右值,则结果对象直接由该表达式初始化。当类型匹配时,该过程不涉及拷贝或移动构造函数(参见
拷贝消除
)。
(since C++17)
功能测试宏
值
标准
功能
__cpp_implicit_move
202207L
(C++23)
简化的
隐式移动
关键词
return
,
co_return
示例
运行此代码
#include
#include
#include
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
{
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
语句
