const和constexpr进一步思考

2024-05-30 02:04

本文主要是介绍const和constexpr进一步思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

        首先如果你对constexpr不了解,还是不太合适.

        这篇文章主要还写我自己在用constexpr遇到的一些疑问.

const比constexpr更加灵活

普通全局变量:

首先,一般的普通全局变量在程序的运行时进行初始化。具体地说,它们在程序进入main函数之前的启动阶段被初始化。也就是在编译期间不会确定值.

constexpr-编译时常量:

        一定是编译期确定变量的值.

constexpr-运行时常量:

        一定会报错,它只能编译期来确定值.

const-编译时常量:

        const int x = 5; // 编译时常量

const-运行时常量:

        const int y = time(nullptr);//正常运行!!

        //constexpr int y = time(nullptr);//报错!!

从上面看出,const比constexpr更加灵活!const既可以编译的时候来确定值,在不能编译时期确定的情况下,可以在运行时期确定变量的值.那么constexpr还有什么要引入的必要吗?

两者几乎不都等价了?

那么普通的全局变量是什么时候确定值?

拓展一下:

  • 普通全局变量在程序的运行时进行初始化。具体地说,它们在程序进入main函数之前的启动阶段被初始化。

const和constexpr几乎等价吗?

几乎等价,但是他又区别!

c++11,引入了constexpr想做的事,是在继承了const在编译期间的特性之后,增加一些功能!

而这个功能就是增加了对函数在编译期间确定值,也就是为什么这个关键字是const+expr组成,非常的贴切!

多说一句;expr的翻译就是表达式.c++中对于'表达式'这个词语的表达包括了变量和函数.

修饰变量的时候,constexpr几乎和const等价.都是编译期间对变量进行确定值.也就是constexpr中的const.

同时.在编译期间可以对函数确定值.也就是constexpr中的expr.

constexpr和const的作用域

普通全局变量:

        范围是所有的cpp文件,只要你加了extern就可以引用.

        非const全局变量具有外部链接。外部链接意味着这个变量在整个程序中是可见的。因此,如果在多个翻译单元中定义了相同名称的非const全局变量,链接器会检测到重复定义并报错。

const:

        范围只本cpp文件中.所以不同文件中相同的变量名不会造成重复.所以用extern引用就报错.

        const全局变量具有内部链接.每个翻译单元都有自己的独立副本,不会与其他翻译单元中的同名变量冲突。

constexpr:

        范围只本cpp文件中.所以不同文件中相同的变量名不会造成重复.

        这个同理const.

既然两者范围都是本文件,那么等同于加了static吗?

如果单纯从作用范围来看,是一样的.

但是static还有其他的属性,这些属性是要保留的.

比如修饰静态变量的时候,生命周期该怎么来就怎么来了.

如何在其他文件引用constexpr修饰的函数呢?

1:声明放在头文件,实现放在源文件

        不行!只能放在头文件中

2:直接放在头文件中实现(推荐)

        也可以直接在头文件中定义constexpr函数,以便编译器更好地进行内联优化。

        我在vs2017上试了,没问题.

// math.h
#ifndef MATH_H
#define MATH_H// 在头文件中定义 constexpr 函数
constexpr int factorial(int n) {return (n <= 1) ? 1 : (n * factorial(n - 1));
}#endif // MATH_H// main.cpp
#include <iostream>
#include "math.h"int main() {constexpr int fact5 = factorial(5); // 使用 constexpr 函数std::cout << "Factorial of 5: " << fact5 << std::endl;return 0;
}

如何在其他文件引用constexpr修饰的变量呢?

1:头文件中定义constexpr变量

        通常,如果你希望在多个翻译单元中使用同一个constexpr变量,最好将其定义在头文件中,并且通常使用inline关键字(c++17)来确保它具有外部链接且避免重复定义错误。

// config.h
#ifndef CONFIG_H
#define CONFIG_H// 在头文件中定义 inline constexpr 变量
inline constexpr int BUF_LEN = 100;#endif // CONFIG_H// main.cpp
#include <iostream>
#include "config.h"int main() {std::cout << "Buffer length: " << BUF_LEN << std::endl;return 0;
}

2:定义在源文件中,加extern,可能是不行的.

        为了在多个翻译单元中引用constexpr变量,应在头文件中使用inline constexpr进行定义.

        如果尝试用extern关键字声明constexpr变量,会导致编译错误,因为constexpr变量的默认行为是内部链接性,不能在另一个翻译单元中找到其定义。

c++17中引入inline的新特性

一般来说,我们在头文件中定义了变量,这个头文件被引用了多次,就会报'多重定义'的问题,

这个时候inline就可以解决这个问题.,使用inline关键字可以避免这种链接错误,因为它允许多个翻译单元共享同一个内联函数的副本。

这篇关于const和constexpr进一步思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015269

相关文章

关于如何更好管理好数据库的一点思考

本文尝试从数据库设计理论、ER图简介、性能优化、避免过度设计及权限管理方面进行思考阐述。 一、数据库范式 以下通过详细的示例说明数据库范式的概念,将逐步规范化一个例子,逐级说明每个范式的要求和变换过程。 示例:学生课程登记系统 初始表格如下: 学生ID学生姓名课程ID课程名称教师教师办公室1张三101数学王老师101室2李四102英语李老师102室3王五101数学王老师101室4赵六103物理陈

OC 中的*前const与*后const

int const *p2; int *const p3; 这个什么不能改由const后面的内容决定,如果是*p的话,则*p不可以改。 也就是说p指向的内容不能改变 如果const后面是p的话,则p不能改,也就是说p的指向不可以改变 OC中的字符串的话 NSString* name=@"wangning"; 此时我们不想让外界改变name的值得话const应该加在 NS

OC和 C语言中的const

const与宏对比 1.都是在其他的地方不可以改变 2.一个地方改了其他的地方都会改变。 而且宏定义的缺陷是, 是它会不断的开辟临时变量的存储空间 使用const的话 是都去使用同一的一份空间,使用同一个对象。 加const 之后变量还是全局的,只不过变为全局常量。 如果此时改变量不想被被类外面访问的话,可以加上static关键字, 3.下次想要定义一些宏的时候分

爬虫阶段思考

内容:写这篇文章是因为最近帮同学改了很多的爬虫代码,感触良多。 我用豆瓣为例,并不是不会用别的,而是这个我个人感觉最经典。然后还会写我遇到的一些问题以及解决方法。 首先,我们得先知道怎样爬取。我用的scrapy框架爬取。 我对此图的理解就是: 从spiders中获得一个请求(REQUEST),通过引擎传递给调度器,之后再返回给引擎,引擎把url封装好后传递给下载器,下载器将资源下载好后

关于微信没有接入鸿蒙NEXT的思考

6月21日,纯血鸿蒙发布,国内的质疑声终于停止,不再被人喊叫换皮 Android 了.就连编程语言都是华为自研的。 可是发布会后微信却成了热点,因为余承东在感谢了一圈互联网企业,如:淘宝、支付宝、美团、京东、抖音、今日头条、钉钉、小红书、微博、B站、高德、WPS等等. 唯独没有感谢腾讯. 中国互联网巨头只有哪么几家,腾讯、阿里、字节、拼多多、美团、百度、京东、华为 他们这些派系又诞生了无数

基于RAG的知识库AI代理机器人,问题思考

基于RAG的知识库AI代理机器人,问题思考 知识库内容分类 对于普通非qa问答格式的知识内容 在分段存储时,需要手动调整,保证每个分段的内容意思完整,不被分割,当然段落也不宜过长,保证内容表达的意思到不可分割为止就行 对于qa问答格式的知识内容 通常需要对问题增加格外索引,因为fastgpt的模式是将问题和回答,作为完整的文本作为向量化的坐标,当问题和回答的内容过长时,使用问题向量化匹配

05-5.5.3 并查集的进一步优化

👋 Hi, I’m @Beast Cheng 👀 I’m interested in photography, hiking, landscape… 🌱 I’m currently learning python, javascript, kotlin… 📫 How to reach me --> 458290771@qq.com 喜欢《数据结构》部分笔记的小伙伴可以订阅专栏,今后还会

关于后台实践的一些疑问、思考与建议

1. 关于工具类 建议一个公司或者一个产品线的项目,使用统一的工具包,而不是每个项目都建立自己的工具类。包括一些枚举类,基础抽象类等也建议加到项目的基础工具包中。 如果要在自己项目中编写的工具类,尽量多实现一些常用的函数。或者让工具类直接继承一些框架中的常用工具类,如StringUtils可以继承common.lang中的StringUtils。 2. 关于日期和时间 从contro

一个问题的思考

问题:在32位的机器上对long型变量进行加减操作存在并发隐患,那么到底是不是这样的呢? 分析:long类型是64位,所以在32位机器上,对long类型的数据操作通常需要多条指令组合出来 ,无法保证原子性,所以并发的时候会出现问题。 对于JAVA并发编程中的一些问题: 可见性问题: 对于可见性,我们先看下定义: 可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到。并发问题往往都是

Android不能调用java.awt的原因及解决办法和思考

android 里面不能使用awt,底层没有具体的实现awt android里面的窗口创建过程决定了界面只能是android里面的组建。 android的组件都是通过远程的IPC调用完成的,也就是说服务端有什么功能才能用什么功能。 不是所有用java写的程序都能在标准jvm中运行的。 android中的虚拟机是修改过的,跟标准的JVM不同,比如对一张图片的解析,android