让我们探索 C++23 的特性!我们将讨论如何consteval从非显式常量评估函数中调用函数。
这个新特性也是一个很好的例子,可以看到 C++ 是如何演变的。C++20 引入了 2 个新关键字,consteval和constinit.
if consteval是什么?
C++中的const*语法数量明显在增长。const是原始语言的一部分,然后C++ 20得到constexpr. C++11。C++17 引入if constexpr,C++20 给我们带来了constevaland constinit,而随着 C++23 我们将得到if consteval(通常被称为consteval if)。
让我们看看添加的内容是什么。
一个consteval if 语句没有条件。最好说,这是条件本身。如果它是在一个明显的常量评估上下文中评估的,则执行以下复合语句。否则,它不是。如果存在else分支,它将按照预期执行。
如果这有助于提高可读性,您也可以使用if !consteval. 以下两段代码是等价的。
if !consteval {
foo();
} else {
bar();
}
// same as
if consteval {
bar();
} else {
foo();
}
如何调用consteval函数?
为了回答这个问题,让我们提醒我们 constexpr和consteval函数之间的区别。函数的constexpr返回值可以在编译时或运行时计算。的consteval函数保证在编译时执行,也称为立即函数。
在 C++ 中,我们倾向于将越来越多的计算转移到编译时间。因此,我们略微增加了编译时间(尽管由于更好的编译器和更强大的计算机,它仍然会下降),但我们加快了运行时间。遵循这些趋势并受益于编译时计算,您可能希望从函数中constexpr 调用函数consteval。但它不适用于 C++20。
consteval int bar(int i) {
return 2*i;
}
constexpr int foo(int i) {
return bar(i);
}
int main() {
[[maybe_unused]] auto a = foo(5);
}
/*
In function 'constexpr int foo(int)':
error: 'i' is not a constant expression
| return bar(i);
| ~~~^~~
*/
这说得通。毕竟,foo(int)是一个constexpr函数,它也可以在运行时执行。但是,如果您真的想在编译时执行函数时从函数constexpr中调用consteval函数怎么办?
在 C++20 中,consteval函数可以调用函数constepxr,但反过来不行。即使您尝试用 包围consteval函数的调用std::is_constant_evaluated(),它也不会改变。下面的例子是行不通的,因为i它仍然不是一个常量表达式:
consteval int bar(int i) {
return 2*i;
}
constexpr int foo(int i) {
if (std::is_constant_evaluated()) {
return bar(i);
}
return 2*i;
}
int main() {
[[maybe_unused]] auto a = foo(5);
}
/*
main.cpp: In function 'constexpr int foo(int)':
main.cpp:6:14: error: 'is_constant_evaluated' is not a member of 'std'
6 | if (std::is_constant_evaluated()) {
| ^~~~~~~~~~~~~~~~~~~~~
main.cpp:7:19: error: 'i' is not a constant expression
7 | return bar(i);
| ~~~^~~
*/
该提案通过添加新的语言特性if consteval来修复它。使用它从 constexpr 调用 consteval 函数。事实上,不仅来自 constexpr ,而且来自任何函数。只要确保您设置了-std=c++2b编译器标志。
consteval int bar(int i) {
return 2*i;
}
int foo(int i) {
if consteval {
return bar(i);
}
return 2*i;
}
int main() {
[[maybe_unused]] auto a = foo(5);
}
虽然if consteval行为与if (std::is_constant_evaluated 完全一样),但它优于它,因为它不需要包含任何头文件,它的语法非常清晰,而且如果它的计算结果为 true,你可以调用 consteval 函数。
结论
在本文中,我们了解了一个新的 C++ 特性,if consteval它可以帮助我们consteval在上下文是常量求值时调用函数,但它没有明确声明。
--------------------------------------------------------
UCanCode E-Form++工业可视化图形C++源码组件库更新并支持最新的C++ 2023,源码下载可以访问UCanCode网址 UCanCode Software。