当前位置: 首页 > news >正文

C++ const、constexpr与consteval作用与区别

C++ const、constexpr与consteval作用与区别

在这里插入图片描述

在C++ 常量表达式和编译时优化中,我们已经提到了常量、编译时常量与运行时常量的概念。为了加深理解,我们再重新明晰一下这三者的概念。

  • 常量:初始化之后便不可修改的量。在c++中使用const修饰的“变量”称为常量。const修饰的常量可以是编译时常量,也可以是运行时常量。现代编译器将自行推理决断。

    #include<iostream>
    int main(){const int x{1};std::cout << x << std::endl;//可以读取x = 5; //error,编译错误,常量不可修改
    }
    
  • 编译时常量:在编译时,编译器将常量的值计算出来,不必等到每次运行时计算。

    #include<iostream>
    int main(){const int x{1 + 8};std::cout << x << std::endl;
    }
    

    就像上面的代码,若不优化,则每次运行编译后的程序时都需要计算 1 + 8 1+8 1+8,如果程序执行一百万次,则 1 + 8 1+8 1+8将被计算一百万次。这完全是没有必要的。
    优化后的结果类似以下代码:

    #include<iostream>
    int main(){const int x{9};std::cout << x << std::endl;
    }
    
  • 运行时常量:程序运行时才确定下来的常量。

    #include<iostream>
    int main(){int a = 9;const int x{a}; //由于a是一个变量,所以x只能在运行到此处的时候才能确定值。std::cout << x << std::endl;
    }
    

constexpr

尽管现代编译器已经可以自主判断是否应该编译时优化,但是由于某些表达式十分复杂,仅仅依赖于编译器是十分困难的。于是c++提供了constexpr关键字,它告诉编译器其修饰的常量是编译时常量可以在编译时优化。

注意: constexpr表示该对象可以在常量表达式中使用。初始值设定项的值在编译时必须已知。constexpr对象可以在运行时或编译时进行计算。constexprstd::string、std::vector和其他使用动态内存分配的类型不完全兼容。

#include <iostream>double nonconstexpr_ex(double radius)
{constexpr double pi { 3.14159265359 };return 2.0 * pi * radius;
}
constexpr double constexpr_ex(double radius)
{constexpr double pi { 3.14159265359 };return 2.0 * pi * radius;
}
int main()
{constexpr double circumference { nonconstexpr_ex(3.0) }; // 编译错误constexpr double circumference { constexpr_ex(3.0) }; // 正确std::cout << "Our circle has circumference " << circumference << "\n";return 0;
}

  1. constexpr 函数也可以在运行时进行计算。所以在非必要时,编译器可自行选择函数是否在编译时计算。
  2. constexpr 函数是隐式内联的, 编译器必须能够看到constexpr(或 consteval)函数的完整定义,而不仅仅是前向声明。

consteval

constevalc++20引入的关键字。用于指示函数必须在编译时计算,否则将导致编译错误。此类函数称为即时函数(immediate functions)。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • R 语言学习教程,从入门到精通,R的安装与环境的配置(3)
  • 信号相关函数
  • Python | Leetcode Python题解之第318题最大单词长度乘积
  • 药店管理小程序的设计
  • 半导体芯闻--20240804
  • c++ malloc 过大或者0
  • ESP32人脸识别开发- 基础介绍(一)
  • MySQL-InnoDB引擎
  • 图论① dfs | Java | LeetCode 797,Kama 98 邻接表实现(未完成)
  • 自动气象站:高度自动化、智能化和精准化
  • Ubuntu配置Ngbatis学习环境
  • C++适配器
  • golang国内proxy设置
  • 【每日一题】【枚举】【估计时间复杂度】[蓝桥杯 2024 省 B] 好数 C++
  • 【Python 逆向滑块】(实战五)逆向滑块,并实现用Python+Node.js 生成滑块、识别滑块、验证滑块、发送短信
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 30天自制操作系统-2
  • CentOS6 编译安装 redis-3.2.3
  • idea + plantuml 画流程图
  • Java 多线程编程之:notify 和 wait 用法
  • node-glob通配符
  • Python爬虫--- 1.3 BS4库的解析器
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • vue 配置sass、scss全局变量
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 翻译--Thinking in React
  • 分布式任务队列Celery
  • 给Prometheus造假数据的方法
  • 简单易用的leetcode开发测试工具(npm)
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 爬虫模拟登陆 SegmentFault
  • 数组大概知多少
  • 我是如何设计 Upload 上传组件的
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • 你对linux中grep命令知道多少?
  • MyCAT水平分库
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 国内开源镜像站点
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • #systemverilog# 之 event region 和 timeslot 仿真调度(十)高层次视角看仿真调度事件的发生
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (C)一些题4
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (附源码)ssm失物招领系统 毕业设计 182317
  • (六)激光线扫描-三维重建
  • (学习日记)2024.01.09
  • (转)创业家杂志:UCWEB天使第一步
  • (转)负载均衡,回话保持,cookie
  • (转载)利用webkit抓取动态网页和链接
  • .gitignore文件设置了忽略但不生效
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .mp4格式的视频为何不能通过video标签在chrome浏览器中播放?
  • .NET C# 操作Neo4j图数据库