基本含义和语法

这两个关键字都可以在对象声明和函数中使用。应用于对象的基本区别是:

  • const声明一个对象为常量。这意味着一个保证,一旦初始化,该对象的值不会改变,编译器可以利用这个事实进行优化。它还有助于防止程序员编写修改初始化后不打算修改的对象的代码。
  • constexpr声明一个对象适合在Standard调用常量表达式中使用。但请注意,这constexpr不是唯一的方法。

应用于功能的基本区别是:

  • const只能用于非静态成员函数,而不能用于一般函数。它保证了成员函数不会修改任何非静态数据成员。
  • constexpr可以与成员和非成员函数以及构造函数一起使用。它声明了适用于常量表达式的函数。如果函数符合某些标准(7.1.5 / 3,4),编译器将只接受它,最重要的是(†):
    • 函数体必须是非虚拟的,非常简单:除typedef和静态断言之外,只return允许一个语句。在构造函数的情况下,只允许初始化列表typedefs和静态声明。(= default= delete也被允许使用,但。)
    • 参数和返回类型必须是文字类型(即一般来说,非常简单的类型,通常是标量或集合)

常量表达式

如上所述,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; }

我什么时候可以同时使用constconstexpr 一起使用?

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被声明为一个地址常量表达式,即一个本身就是一个常量表达式的指针。(当通过将地址运算符静态/全局常量表达式生成的地址。这是可能的。)在这里,无论是constexprconst是必需的:constexpr总是指表达被宣布(在这里NP),而const指的是int(它声明了一个指针-给const)。删除const会导致表达式不合法(因为(a)非const对象的指针不能是常量表达式,(b)&N实际上是指向常量的指针)。

B.在成员函数声明中。在C ++ 11中,也constexpr暗示const了成员函数。但是,这在C ++ 14中可能会改变。根据目前的草案,由于建议修改§7.1.5/ 8 ,constexprconst 仅针对对象,而不针对成员职能。因此,在C ++ 11下声明一个成员函数为

constexpr void f();

将不得不被宣布为

constexpr void f() const;

在C ++ 14下仍然可以用作const函数。最好将你的constexpr成员函数标记为const现在,以免稍后改变很多代码。

`constexpr`和`const`之间的区别?相关推荐

  1. 轻松弄懂var、let、const之间的区别(一看就懂)

    ES6的好处 ES6的出现为我们前端带来了很多方便之处,以前用js几十行才实现的一个功能,ES6几行代码就能简单的实现,ES6新增的一些特性,改变了很多弊端之处,比如新出现的let.const,实现了 ...

  2. 轻松弄懂var、let、const之间的区别

    ECMAScript 6(简称ES6)是JavaScript语言的下一代标准,于2015年6月正式发布,也称ECMAScript 2015. ES6的好处 ES6的出现为我们前端带来了很多方便之处,以 ...

  3. 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 ...

  4. const int *,const int * const和int const *之间的区别

    文章目录 int const* int *const const int* const 记忆图 参考文档 int const*     int const* 是指向常量整数的指针.     这意味着被 ...

  5. define宏定义和const定义之间的区别

    define部分: 宏不仅可以用来代替常数值,还可以用来代替表达式,甚至是代码段.(宏的功能很强大,但也容易出错,所以其利弊大小颇有争议.) 宏的语法为: #define 宏名称 宏值 注意,宏定义不 ...

  6. C++day01 const和define之间的区别

    大家好,我是阿林,一个c++的初学者.记录我学习c++的过程. 今天主要讲的是 const和define之间的区别 const和define都是定义常量,但是它们却有着定义域,作用域上的不同. def ...

  7. ES6 | let、const以及与var之间的区别

    目录 一.let 1.声明变量 2.块儿级作用域 3.不存在变量提升 4.不影响作用域链 二.const 1.声明常量 2.一般常量使用大写(潜规则) 3.常量的值不能修改 4.块儿级作用域(cons ...

  8. 【待续】C#.Net 关键词清理 Fields Property Attribute Const三者之间的区别与联系

    C#.Net 关键词清理 Fields Property Attribute 三者之间的区别与联系 不少人一直对这三个词容易混淆视听,不知道他们之间到底什么联系. 这可能跟翻译的中文有很大的关系. 首 ...

  9. const int *,const int * const和int const *有什么区别?

    我总是搞砸了如何正确使用<code>const int* , const int * const和int const * . 是否有一组规则定义您可以做什么和不能做什么? 我想知道在分配, ...

最新文章

  1. python获取mac、计算机id_python 获取本机IP、mac地址、计算机名的简单示例
  2. 全球与中国OLED大平板涂胶显影设备市场运营状况分析及投资前景建议报告2022-2028年版
  3. 苹果手机怎么清理听筒灰尘_安卓 | 让手机自动清理听筒扬声器灰尘,你试过了吗?...
  4. appconfig文件中的配置节
  5. 微软发布 .NET for Apache Spark 首个预览版
  6. 图像处理之调整亮度与饱和度
  7. linux一次性密码确保ssh登录安全,使用 SSH 时确保 EC2 Linux 实例安全的最佳实践
  8. 【渝粤教育】国家开放大学2018年春季 8618-21T燃气行业规范 参考试题
  9. (SDL2)SDL在ubuntu下的测试代码(雷霄骅)
  10. java poi html转PDF_实现word转pdf,HTML转pdf(探索篇)
  11. 原来微信还有隐藏代码,80%的用户还不知道!(附表白代码)
  12. GCN的Python实现与源码分析
  13. C#删除word页眉页脚和最后一页
  14. Windows——matplotlib添加中文字体
  15. 这些优秀的 Spring Cloud 开源软件,你知道的有几个?
  16. 美国留学申请干货--转自 AdmitWrite留学(无图)
  17. 【Linux上安装Scala】
  18. 创客学院9天C语言三
  19. php trait instanceof,Hyperf 验证 trait
  20. 使用teensy 2.0++ 开发板模拟U盘

热门文章

  1. MVVM模式的3种command总结[2]--RelayCommand
  2. Easyui入门视频教程 第11集---Window的使用
  3. 【数据结构与算法】之深入解析“扁平化多级双向链表”的求解思路与算法示例
  4. 1.3 Hive架构原理
  5. 785. Is Graph Bipartite? 判断二分图
  6. Python内存管理方式和垃圾回收算法解析
  7. BASIC-1 闰年判断
  8. The directory '*' or its parent directory is not owned by the current user
  9. 信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言——1103:陶陶摘苹果
  10. 【Linux】一步一步学Linux——Centos7.5安装图解(08)