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;
}

image

由于重力是常量表达式且初始化值为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;
}

image

当上述代码被编译时,编译器会在编译时求值该条件语句,发现其始终为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。这将确保编译时求值得以执行(即使禁用优化)。

posted @ 2026-02-25 16:23  游翔  阅读(1)  评论(0)    收藏  举报