constexpr限定符和常量表达式

2024-01-14 17:08

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

定义

常量表达式(const expression)是指值不会改变并且在编译过程就能得到结果的表达式。

字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。

const int a = 4;	//字面值4是常量表达式,a 是一个const int对象,我们用常量表达式初始化它,因此a也是常量表达式
const string s = "str";	//同理s也是常量表达式

一个对象(或表达式)是不是常量表达式由它们的数据类型和初始值共同决定,例:

const int a = 20;	//初始值是常量表达式,因此const int对象a也是常量表达式
const int b = a + 1;	//a + 1是常量表达式,所以b是常量表达式
int c = 27;			//c 是一个int对象(变量),即使初始值是常量表达式
const int d = size();	//d不是常量表达式,因为其初始值size() 的返回值要到运行时才能得到。

constexpr变量

c++11标准允许声明constexpr类型的变量,声明为constexpr的变量一定是一个常量,而且必须使用常量表达式初始化。

constexpr int a = 20;	//20是常量表达式,a是一个常量
constexpr int b = a + 1;	//a + 1是常量表达式
constexpr int c = size();	//只有当size是一个constexpr函数(用constexpr修饰的函数在编译时就可以计算其结果了)时c才是常量

constexpr指针

也可用constexpr限定符声明指针,但仅对指针有效,与指针所指向的对象无关。

const int* p = nullptr;		//p是一个指向常量的指针,底层const:表示指针所指向的对象是一个常量
constexpr int* q = nullptr;	//q是一个指向整数的常量指针,顶层const:表示指针本身是个常量

constexpr指针既可以指向常量也可以指向一个非常量对象。

constexpr int* p = nullptr;	//np是一个指向常量的常量指针,其值为空
constexpr int i = 0;
int j = 4;
constexpr const int* q = &i;	//q是一个指向常量的常量指针,指向整型常量i
constexpr int* t = &j;			//t是常量指针,指向一个变量j

constexpr函数

constexpr 函数(constexpr function)是指能用于常量表达式的函数。

定义constexpr函数的方法与其他函数类似,不过要遵循几项约定:

①函数的返回类型及所有形参的类型都得是常量表达式。
②函数体中必须有且只有一条return语句。

constexpr int func() { return 42; } 	//func是一个无参的constexpr函数,程序在编译时验证该函数返回的是常量表达式
constexpr int a = func();			//a是一个常量表达式。编译器把对func的调用替换成其结果值。

因为要在编译过程中随时展开,constexpr函数被隐式地指定为内联函数。

常量表达式的适用场景

①指定数组的边界

int i = 99;
int a[i];		//错误,i不是一个常量表达式
constexpr int j = 99;
int b[j];		//正确,j是一个常量表达式

②指定非类型模板参数的值

template<unsigned size >
void test()
{//函数体
}test<i> f;	//显示传入模板实参,并声明一个函数对象f。错误,因为i不是常量表达式
test<j> f2;	//正确,j是一个常量表达式

③在类定义中,为一个static const的整数类型的数据成员提供一个初始化器

const int x = 5;
class X
{
static const int x_ = x;	//正确,x是一个常量表达式
};

这篇关于constexpr限定符和常量表达式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

如何掌握面向对象编程的四大特性、Lambda 表达式及 I/O 流:全面指南

这里写目录标题 OOP语言的四大特性lambda输入/输出流(I/O流) OOP语言的四大特性 面向对象编程(OOP)是一种编程范式,它通过使用“对象”来组织代码。OOP 的四大特性是封装、继承、多态和抽象。这些特性帮助程序员更好地管理复杂的代码,使程序更易于理解和维护。 类-》实体的抽象类型 实体(属性,行为) -》 ADT(abstract data type) 属性-》成

Java基础回顾系列-第三天-Lambda表达式

Java基础回顾系列-第三天-Lambda表达式 Lambda表达式方法引用引用静态方法引用实例化对象的方法引用特定类型的方法引用构造方法 内建函数式接口Function基础接口DoubleToIntFunction 类型转换接口Consumer消费型函数式接口Supplier供给型函数式接口Predicate断言型函数式接口 Stream API 该篇博文需重点了解:内建函数式

C语言程序设计(数据类型、运算符与表达式)

一、C的数据类型 C语言提供的数据类型: 二、常量和变量 2.1常量和符号常量 在程序运行过程中,其值不能被改变的量称为常量。 常量区分为不同的类型: 程序中用#define(预处理器指令)命令行定义变量将代表常量,用一个标识符代表一个常量,称为符合常量。 2.2变量 变量代表内存中具有特定属性的一个存储单元,用来存放数据,在程序运行期间,这些值是可以 改变的。 变

JavaSE(十三)——函数式编程(Lambda表达式、方法引用、Stream流)

函数式编程 函数式编程 是 Java 8 引入的一个重要特性,它允许开发者以函数作为一等公民(first-class citizens)的方式编程,即函数可以作为参数传递给其他函数,也可以作为返回值。 这极大地提高了代码的可读性、可维护性和复用性。函数式编程的核心概念包括高阶函数、Lambda 表达式、函数式接口、流(Streams)和 Optional 类等。 函数式编程的核心是Lambda

逻辑表达式,最小项

目录 得到此图的逻辑电路 1.画出它的真值表 2.根据真值表写出逻辑式 3.画逻辑图 逻辑函数的表示 逻辑表达式 最小项 定义 基本性质 最小项编号 最小项表达式   得到此图的逻辑电路 1.画出它的真值表 这是同或的逻辑式。 2.根据真值表写出逻辑式   3.画逻辑图   有两种画法,1是根据运算优先级非>与>或得到,第二种是采

将浮点型算式的中缀表达式转换成后缀表达式并算出式子结果

最近因为需要了解如何将在Win应用程序控制台输入的算式表达式转化成其后缀表达式的算法,所以在网上搜索了一下,看到许多人的程序都只是对应于运算数在0~9的范围内的整型运算式,所以自己就写了一个可以计算浮点型算式的程序,一下是运行时的截图: 式子中的a,b,c是可供用户自行输入的变量。 首先,我先对输入的运算符进行了简单的合法性判断,我的判断代 码如下: //函数的传入参

从零开始学习JVM(七)- StringTable字符串常量池

1 概述 String应该是Java使用最多的类吧,很少有Java程序没有使用到String的。在Java中创建对象是一件挺耗费性能的事,而且我们又经常使用相同的String对象,那么创建这些相同的对象不是白白浪费性能吗。所以就有了StringTable这一特殊的存在,StringTable叫做字符串常量池,用于存放字符串常量,这样当我们使用相同的字符串对象时,就可以直接从StringTable