8.4 constexpr if 语句
通常,if语句的条件表达式会在运行时进行求值。
然而,当条件表达式为常量表达式时,情况则有所不同,如下例所示:
#include <iostream>
int main()
{
constexpr double gravity{ 9.8 };
// reminder: low-precision floating point literals of the same type can be tested for equality
if (gravity == 9.8) // constant expression, always true
std::cout << "Gravity is normal.\n"; // will always be executed
else
std::cout << "We are not on Earth.\n"; // will never be executed
return 0;
}

由于重力是常量表达式且初始化值为9.8,条件语句重力 == 9.8 必须求值为真。因此else语句永远不会被执行。
在运行求值常量表达式条件语句是浪费资源的(因为结果永远不会改变)。将永远不会被执行的代码编译到可执行文件中同样是资源浪费。
Constexpr if 语句(C++17)
C++17引入了constexpr if 语句constexpr if statement,该语句要求条件表达式为constant表达式。constexpr if 语句的条件将在编译时求值。
若constexpr条件求值为'true,则整个if-else结构将被替换为 true语句;若constexpr条件求值为false`,则整个if-else结构将被替换为 false语句(若存在else语句)或保持原状(若无else语句)。
使用constexpr-if 语句时,需在if后添加constexpr关键字:
#include <iostream>
int main()
{
constexpr double gravity{ 9.8 };
if constexpr (gravity == 9.8) // now using constexpr if
std::cout << "Gravity is normal.\n";
else
std::cout << "We are not on Earth.\n";
return 0;
}

当上述代码被编译时,编译器会在编译时求值该条件语句,发现其始终为true,因此仅保留单条语句:std::cout << "Gravity is normal.\n";
换言之,它将编译以下内容:
int main()
{
constexpr double gravity{ 9.8 };
std::cout << "Gravity is normal.\n";
return 0;
}
最佳实践
当条件为constant表达式时,优先使用constexpr if 语句语句而非non-constexpr if语句。
现代编译器与含constexpr条件的if语句(C++17)
出于优化目的,现代编译器通常会将具有constexpr条件的non-constexpr if语句视为constexpr if语句处理。但编译器并非必须如此操作。
当编译器遇到包含 constexpr 条件的non-constexpr if 语句时,可能会发出警告,建议改用 if constexpr。这将确保编译时求值得以执行(即使禁用优化)。

浙公网安备 33010602011771号