`constexpr`和`const`之间的区别?
基本含义和语法
这两个关键字都可以在对象声明和函数中使用。应用于对象的基本区别是:
const
声明一个对象为常量。这意味着一个保证,一旦初始化,该对象的值不会改变,编译器可以利用这个事实进行优化。它还有助于防止程序员编写修改初始化后不打算修改的对象的代码。constexpr
声明一个对象适合在Standard调用常量表达式中使用。但请注意,这constexpr
不是唯一的方法。
应用于功能的基本区别是:
const
只能用于非静态成员函数,而不能用于一般函数。它保证了成员函数不会修改任何非静态数据成员。constexpr
可以与成员和非成员函数以及构造函数一起使用。它声明了适用于常量表达式的函数。如果函数符合某些标准(7.1.5 / 3,4),编译器将只接受它,最重要的是(†):- 函数体必须是非虚拟的,非常简单:除typedef和静态断言之外,只
return
允许一个语句。在构造函数的情况下,只允许初始化列表typedefs和静态声明。(= default
和= delete
也被允许使用,但。) - 参数和返回类型必须是文字类型(即一般来说,非常简单的类型,通常是标量或集合)
- 函数体必须是非虚拟的,非常简单:除typedef和静态断言之外,只
常量表达式
如上所述,constexpr
声明两个对象以及适合在常量表达式中使用的函数。一个恒定的表达不仅仅是不变的:
- 它可用于需要编译时评估的地方,例如模板参数和数组大小说明符:
template<int N> class fixed_size_list { /*...*/ };
fixed_size_list<X> mylist; // X must be an integer constant expression
int numbers[X]; // X must be an integer constant expression
- 但请注意:
- 声明一些东西
constexpr
并不一定保证在编译时会被评估。它可以用于此类,但也可以在运行时评估的其他地方使用。 - 一个对象可能适合在常量表达式中使用,而不需要声明
constexpr
。例:int main() { const int N = 3; int numbers[N] = {1, 2, 3}; // N is constant expression return 0; }
这是可能的,因为
N
在声明时使用常量来保持常量和初始化,即使没有声明,它也满足常量表达式的条件constexpr
。 - 声明一些东西
那么我什么时候需要使用constexpr
?
- 像上面这样的对象
N
可以作为常量表达式使用而不需要声明constexpr
。所有对象都是如此:const
- 积分或枚举类型和
- 在声明时用一个本身就是常量表达式的表达式进行初始化
[这是由于§5.19/ 2:一个常量表达式不能包括一个子表达式,涉及“左值,右值修改,除非[...]整数或枚举类型的glvalue”感谢理查史密斯纠正我早些时候声称这对所有字面类型都是正确的。]
- 要使函数适合在常量表达式中使用,必须明确声明
constexpr
; 仅仅满足常量表达函数的标准是不够的。例:template<int N> class list { };
constexpr int sqr1(int arg) { return arg * arg; }
int sqr2(int arg) { return arg * arg; }
int main() { const int X = 2; list<sqr1(X)> mylist1; // OK: sqr1 is constexpr list<sqr2(X)> mylist2; // wrong: sqr2 is not constexpr return 0; }
我什么时候可以同时使用const
和constexpr
一起使用?
A.在对象声明中。当两个关键字都指向同一个被声明的对象时,这是不必要的。constexpr
意味着const
。
constexpr const int N = 5;
是相同的
constexpr int N = 5;
但是,请注意,可能会出现以下情况:关键字分别指向声明的不同部分:
static constexpr int N = 3;int main() {constexpr const int *NP = &N;return 0; }
在这里,NP
被声明为一个地址常量表达式,即一个本身就是一个常量表达式的指针。(当通过将地址运算符静态/全局常量表达式生成的地址。这是可能的。)在这里,无论是constexpr
和const
是必需的:constexpr
总是指表达被宣布(在这里NP
),而const
指的是int
(它声明了一个指针-给const)。删除const
会导致表达式不合法(因为(a)非const对象的指针不能是常量表达式,(b)&N
实际上是指向常量的指针)。
B.在成员函数声明中。在C ++ 11中,也constexpr
暗示const
了成员函数。但是,这在C ++ 14中可能会改变。根据目前的草案,由于建议修改§7.1.5/ 8 ,constexpr
将const
仅针对对象,而不针对成员职能。因此,在C ++ 11下声明一个成员函数为
constexpr void f();
将不得不被宣布为
constexpr void f() const;
在C ++ 14下仍然可以用作const
函数。最好将你的constexpr
成员函数标记为const
现在,以免稍后改变很多代码。
`constexpr`和`const`之间的区别?相关推荐
- 轻松弄懂var、let、const之间的区别(一看就懂)
ES6的好处 ES6的出现为我们前端带来了很多方便之处,以前用js几十行才实现的一个功能,ES6几行代码就能简单的实现,ES6新增的一些特性,改变了很多弊端之处,比如新出现的let.const,实现了 ...
- 轻松弄懂var、let、const之间的区别
ECMAScript 6(简称ES6)是JavaScript语言的下一代标准,于2015年6月正式发布,也称ECMAScript 2015. ES6的好处 ES6的出现为我们前端带来了很多方便之处,以 ...
- const int a; int const a; const int *a; int * const a; int const * a const; 之间的区别
const int a; int const a; const int * a; int * const a; int const * const; 之间的区别 const int a; int co ...
- const int *,const int * const和int const *之间的区别
文章目录 int const* int *const const int* const 记忆图 参考文档 int const* int const* 是指向常量整数的指针. 这意味着被 ...
- define宏定义和const定义之间的区别
define部分: 宏不仅可以用来代替常数值,还可以用来代替表达式,甚至是代码段.(宏的功能很强大,但也容易出错,所以其利弊大小颇有争议.) 宏的语法为: #define 宏名称 宏值 注意,宏定义不 ...
- C++day01 const和define之间的区别
大家好,我是阿林,一个c++的初学者.记录我学习c++的过程. 今天主要讲的是 const和define之间的区别 const和define都是定义常量,但是它们却有着定义域,作用域上的不同. def ...
- ES6 | let、const以及与var之间的区别
目录 一.let 1.声明变量 2.块儿级作用域 3.不存在变量提升 4.不影响作用域链 二.const 1.声明常量 2.一般常量使用大写(潜规则) 3.常量的值不能修改 4.块儿级作用域(cons ...
- 【待续】C#.Net 关键词清理 Fields Property Attribute Const三者之间的区别与联系
C#.Net 关键词清理 Fields Property Attribute 三者之间的区别与联系 不少人一直对这三个词容易混淆视听,不知道他们之间到底什么联系. 这可能跟翻译的中文有很大的关系. 首 ...
- const int *,const int * const和int const *有什么区别?
我总是搞砸了如何正确使用<code>const int* , const int * const和int const * . 是否有一组规则定义您可以做什么和不能做什么? 我想知道在分配, ...
最新文章
- python获取mac、计算机id_python 获取本机IP、mac地址、计算机名的简单示例
- 全球与中国OLED大平板涂胶显影设备市场运营状况分析及投资前景建议报告2022-2028年版
- 苹果手机怎么清理听筒灰尘_安卓 | 让手机自动清理听筒扬声器灰尘,你试过了吗?...
- appconfig文件中的配置节
- 微软发布 .NET for Apache Spark 首个预览版
- 图像处理之调整亮度与饱和度
- linux一次性密码确保ssh登录安全,使用 SSH 时确保 EC2 Linux 实例安全的最佳实践
- 【渝粤教育】国家开放大学2018年春季 8618-21T燃气行业规范 参考试题
- (SDL2)SDL在ubuntu下的测试代码(雷霄骅)
- java poi html转PDF_实现word转pdf,HTML转pdf(探索篇)
- 原来微信还有隐藏代码,80%的用户还不知道!(附表白代码)
- GCN的Python实现与源码分析
- C#删除word页眉页脚和最后一页
- Windows——matplotlib添加中文字体
- 这些优秀的 Spring Cloud 开源软件,你知道的有几个?
- 美国留学申请干货--转自 AdmitWrite留学(无图)
- 【Linux上安装Scala】
- 创客学院9天C语言三
- php trait instanceof,Hyperf 验证 trait
- 使用teensy 2.0++ 开发板模拟U盘
热门文章
- MVVM模式的3种command总结[2]--RelayCommand
- Easyui入门视频教程 第11集---Window的使用
- 【数据结构与算法】之深入解析“扁平化多级双向链表”的求解思路与算法示例
- 1.3 Hive架构原理
- 785. Is Graph Bipartite? 判断二分图
- Python内存管理方式和垃圾回收算法解析
- BASIC-1 闰年判断
- The directory '*' or its parent directory is not owned by the current user
- 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1103:陶陶摘苹果
- 【Linux】一步一步学Linux——Centos7.5安装图解(08)