有条件地执行另一条语句。
用于需要基于运行时或编译时条件执行的代码。
语法
attr(可选) if ( 条件 ) true分支语句 | (1) | (C++17 前) |
attr(可选) if constexpr (可选) ( 初始化语句(可选) 条件 ) true分支语句 | (1) | (C++17 起) |
attr(可选) if ( 条件 ) true分支语句 else false分支语句 | (2) | (C++17 前) |
attr(可选) if constexpr (可选) ( 初始化语句(可选) 条件 ) true分支语句 else false分支语句 | (2) | (C++17 起) |
attr(C++11) | - | 任意数量的属性 |
条件 | - | 下列之一 - 按语境转换为 bool 的表达式 - 单个非数组变量的带花括号或等号初始化器的声明。 |
初始化语句(C++17) | - | 下列之一 - 一条表达式语句(可以是空语句“ ; ”)- 一条简单声明,典型的是带初始化器的变量声明,但它可以声明任意多变量,或是一条分解声明 - 注意,任何 初始化语句 必然以分号 ; 结束,这是它常被非正式地描述成后随分号的表达式或声明的原因。 |
true分支语句 | - | 任何语句(常为复合语句),当 条件 求值为 true 时执行 |
false分支语句 | - | 任何语句(常为复合语句),当 条件 求值为 false 时执行 |
解释
若 条件 在转换到 bool 后产生 true,则执行 true分支语句。
若 if 语句的 else 部分存在,且 条件 在转换到 bool 后产生 false,则执行 false分支语句。
在 if 语句的第二形式(包含 else)中,若 true分支语句 亦是 if 语句,则内层 if 语句必须也含有 else 部分(换言之,嵌套 if 语句中,else 关联到最近的尚未有 else 的 if)。
运行此代码
- #include <iostream>
- int main() {
- // 带 else 子句的简单 if 语句
- int i = 2;
- if (i > 2) {
- std::cout << i << " 大于 2\n";
- } else {
- std::cout << i << " 不大于 2\n";
- }
- // 嵌套 if 语句
- int j = 1;
- if (i > 1)
- if (j > 2)
- std::cout << i << " > 1 且 " << j << " > 2\n";
- else // 此 else 属于 if (j > 2), 而不是 if (i > 1)
- std::cout << i << " > 1 且 " << j << " <= 2\n";
- // 以下声明可用于含 dynamic_cast 的条件
- struct Base {
- virtual ~Base() {}
- };
- struct Derived : Base {
- void df() { std::cout << "df()\n"; }
- };
- Base* bp1 = new Base;
- Base* bp2 = new Derived;
- if (Derived* p = dynamic_cast<Derived*>(bp1)) // 转型失败,返回 nullptr
- p->df(); // 不执行
- if (auto p = dynamic_cast<Derived*>(bp2)) // 转型成功
- p->df(); // 执行
- }
输出:
- 2 不大于 2
- 2 > 1 且 1 <= 2
- df()
#### 带初始化器的 if 语句 若使用 初始化语句,则 if 语句等价于
或
但 初始化语句 所声明的名字(若 初始化语句 是声明)和 条件 所声明的名字(若 条件 是声明)处于同一作用域中,同时也是两条 语句 所在的作用域。
| (C++17 起) |
#### constexpr if 以 if constexpr 开始的语句被称为constexpr if 语句。在 constexpr if 语句中,条件 的值必须是可按语境转换到 bool 类型的经转换常量表达式。若其值为 true ,则舍弃 false分支语句(若存在),否则舍弃 true分支语句。被舍弃语句中的 return 语句不参与函数返回类型推导:
被舍弃语句可以 ODR 式使用未定义的变量
若 constexpr if 语句出现于模板实体内,且若 条件 在实例化后不是值待决的,则外围模板被实例化时不会实例化被舍弃语句。
在模板外,被舍弃语句受到完整的检查。 if constexpr 不是 #if 预处理指令的替代品:
注意:实例化后仍为值待决的一个例子是嵌套模板,例如 注意:被舍弃语句不能对所有特化均非良构:
对这种万应语句的常用变通方案,是一条始终为 false 的类型待决表达式:
在 constexpr if 的子语句中出现的标号(goto 目标、 case 标号和 default: ),只能在同一子语句中(由 switch 或 goto)引用。 | (C++17 起) |
注解
若 true分支语句 或 false分支语句 不是复合语句,则按如同是复合语句一样处理:
- if (x)
- int i;
- // i 不再在作用域中
与下面相同
- if (x) {
- int i;
- } // i 不再在作用域中
条件 若是声明,则其所引入的名字的作用域是两个语句体的合并作用域:
- if (int x = f()) {
- int x; // 错误:重复声明了 x
- } else {
- int x; // 错误:重复声明了 x
- }
若通过 goto 或 longjmp 进入 true分支语句,则不执行 false分支语句。 | (C++14 起) |
不允许 switch 和 goto 跳入 constexpr if 语句的分支。 | (C++17 起) |
关键词
当前内容版权归 cppreference 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 cppreference .