const 和 constexpr 深入学习

在 C++ 中,const 和 constexpr 都可以用来修饰对象和函数。修饰对象时,const 表示它是常量,而 constexpr 表示它是一个常量表达式。常量表达式必须在编译时期被计算1。修饰函数时,const 只能用于非静态成员的函数,而 constexpr 可以用于含参和无参函数。constexpr 函数适用于常量表达式,只有在下面的情况下编译器才会接受 constexpr 函数:

  1. 函数体必须足够简单,除了 typedef 和静态元素,只允许有 return 语句。如构造函数只能有初始化列表,typedef 和静态元素(实际上在 C++14 标准中已经允许定义语句存在于 constexpr 函数体内了)。
  2. 参数和返回值必须是字面值类型。

常量表达式的概念如下:

  • 必须是可以在编译阶段被识别的。比如模版的参数/数组的大小。
  • constexpr 修饰某物并不保证它一定在编译时被计算,也可以在运行时被计算。
  • 不用 constexpr 也可能是一个常量表达式,如 const int N = 3; int num [N] = {1,2,3,};N 在声明时初始化,满足常量表达式的标准,虽然没用 constexpr

所以,到底什么时候用 constexpr?像上面的 N,虽然没有用 constexpr 仍然是一个常量表达式。事实上,const 本身和它的枚举类型若在声明时初始化那么就是一个常量表达式。在函数中若有常量表达式那么必须用 constexpr,仅仅满足常量表达式的条件是不够的。

所以,constconstexpr 的主要区别在于:

  • const 变量的初始化可以延迟到运行时,而 constexpr 变量必须在编译时进行初始化。
  • const 变量可以通过 const_cast 类型转换来修改值,而 constexpr 是不可以修改的。可以将 const 理解为只读变量更符合其含义。
  • const 只能用于非静态成员函数,而 constexpr 可以和成员、非成员、构造函数一起使用。

我们来深入学习代码


int fun(int x) {return x;
}constexpr int ff(int x) {return x;
}int main()
{int x = 10;const int a = x;constexpr int b = x;  // 错误的 表达式 必须是常量constexpr int c = fun(10);   // 也是错误的constexpr int d = ff(10);   // 正确的constexpr int d = ff(x);   // 错误的
}

 

  1. const int a = x; 是正确的,因为 a 是一个常量,可以被赋值为一个变量。

  2. constexpr int b = x; 是错误的,因为 x 不是常量表达式,而 constexpr 变量必须在编译时求值为常量表达式。

  3. constexpr int c = fun(10); 是错误的,因为 fun(10) 返回的不是常量表达式。在 constexpr 上下文中,函数的返回值必须是常量表达式。

  4. constexpr int d = ff(10); 是正确的,因为 ff(10) 返回的是常量表达式。

  5. constexpr int e = ff(x); 是错误的,因为 x 不是常量表达式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/231506.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python实现学生信息管理系统(详解版)

Python实现学生信息管理系统-详解版 个人简介实验名称:学生信息管理系统系统功能实验步骤详讲添加入住学生信息删除学生的住宿信息修改学生的住宿信息查询学生的住宿信息显示所有学生住宿信息显示所有请假学生的信息 运行截图展示1.主界面2.添加新的入住学生信息3.显…

网络通信与TCP.IP协议

网络通信与TCP.IP协议 URI 用字符串标识某一互联网资源,而 URL 表示资源的地点(互联网上所处的位置)。可见 URL 是 URI 的子集 URL (Uniform Resource Locator),统一资源定位符 ,用于描述一个网络上的资源 DNS: &#…

TableAgent:首个国产可私有部署的企业级Code Interpreter

TableAgent公测地址:https://tableagent.DataCanvas.com 数字化时代,数据分析的重要性犹如空气般无处不在。商业数据分析是数字化管理、智能决策的基础,同时数据分析又是一个专业性极强的工作,描述性分析、诊断性分析、预测性分…

版本控制系统Git学习笔记-Git基本知识介绍

目录 前言一、版本控制系统1.1 什么是版本控制系统1.2 本地版本控制系统1.3 集中化的版本控制系统1.3 分布式版本控制系统 二、Git简介2.1 数据处理方式2.2 几个特点2.2.1 几乎所有操作都是本地执行2.2.2 Git保证完整性2.2.3 Git一般只添加数据 2.3 Git中文件状态2.3.1 三种文件…

排序算法基本原理及实现2

📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 🌤️冒泡排序 &#x1…

AI伪原创软件-AI伪原创工具下载

在当今数字化时代,创作者们在追求独特创意的同时,也面临着时间和灵感的双重挑战。AI伪原创技术应运而生,为创作者提供了一种快捷而便利的解决方案。本文将专心分享两款备受瞩目的AI伪原创工具,147SEO伪原创、百度文心一言伪原创&a…

数据结构-02-链表

相比数组,链表是一种稍微复杂一点的数据结构。掌握起来也要比数组稍难一些。这两个非常基础、非常常用的数据结构。 1-链表结构 数组需要一块连续的内存空间来存储,对内存的要求比较高。如果我们申请一个20MB大小的数组,当内存中没有连续的、…

串口理解小结(UART)

串口作为单片机的必备外设,主要用于单片机与其它模块的信息通讯、程序烧录和升级作用。 UART全称为通用异步收发器。 可分为: 一、串行和并行 串行指数据位只能一位一位地发送 并行之多个数据位同时发送 二、同步和异步 同步和异步是相当于时钟而…

【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析

文章目录 行为型模式1、模板方法模式(1)概述(2)结构(3)案例实现(4)优缺点(5)适用场景(6)JDK源码解析(7)模板方…

用customize-cra+react-app-rewired配置less+css module

1. 安装 npm i less less-loader -D npm i customize-cra-less-loader -D2.添加配置项 //config-overrides.js const { override } require(customize-cra); const addLessLoader require("customize-cra-less-loader");module.exports {webpack: override(addL…

爬虫学习 逆向爬虫(六)

多任务异步协程 协程:更高效的利用CPU import timedef func():print("黎明")time.sleep(3)print("还是黎明")func() 等待时机长 sleep时CPU不再工作 IO操作(费时不费力)->阻塞 线程运行阻塞后 移出主线程 移动到下一个 4个任务一个线程 …

通用plantuml模板头

通用plantuml文件 startuml participant Admin order 0 #87CEFA // 参与者、顺序、颜色 participant Student order 1 #87CEFA participant Teacher order 2 #87CEFA participant TestPlayer order 3 #87CEFA participant Class order 4 #87CEFA participant Subject order …