C++23: Consteval if 使编译时编程更容易

让我们探索 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。 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值