一、在普通函数中的使用

例如下面的代码,

数组的大小必须是常量,在声明数组array时,用函数返回值,此时会报错:

error C2131: 表达式的计算结果不是常数

note: 对未定义的函数或为未声明为“constexpr”的函数的调用导致了故障

用constexpr关键字可以解决这种问题,在GetLen函数前加constexpr声明,代码如下:

当然,constexpr修饰的函数也有一定的限制:
     (1)函数体尽量只包含一个return语句,多个可能会编译出错;
       (2)函数体可以包含其他语句,但是不能是运行期语句,只能是编译期语句;

编译器会将constexpr函数视为内联函数!所以在编译时若能求出其值,则会把函数调用替换成结果值。

二、在类的构造函数中也可以使用constexpr关键字

constexpr还能修饰类的构造函数,即保证传递给该构造函数的所有参数都是constexpr,那么产生的对象的所有成员都是constexpr。该对象是constexpr对象了,可用于只使用constexpr的场合。 
        注意constexpr构造函数的函数体必须为空,所有成员变量的初始化都放到初始化列表中。

代码如下:

#include <iostream>
using namespace std;class Test
{
public:constexpr Test(int num1, int num2) : m_num1(num1), m_num2(num2){}public:int m_num1;int m_num2;
};int main(void)
{constexpr Test t1(1, 2);enum e{ x = t1.m_num1, y = t1.m_num2 };return 0;
}

如果在构造函数中加点代码,就会编译报错,如下:

三、const和constexpr对指针的修饰有什么差别呢?

(1)const 和 constexpr 变量之间的主要区别在于:const 变量的初始化可以延迟到运行时,而 constexpr 变量必须在编译时进行初始化。所有 constexpr 变量均为常量,因此必须使用常量表达式初始化。

(2)constexpr和指针
       在使用const时,如果关键字const出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针本身是常量;如果出现在星号两边,表示被指物和指针两者都是常量。

与const不同,在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效,与指针所指对象无关。

constexpr是一种很强的约束,更好的保证程序的正确定语义不被破坏;编译器可以对constexper代码进行非常大的优化,例如:将用到的constexpr表达式直接替换成结果, 相比宏来说没有额外的开销。

代码:

#include <iostream>
using namespace std;int g_tempA = 4;
const int g_conTempA = 4;
constexpr int g_conexprTempA = 4;int main(void)
{int tempA = 4;const int conTempA = 4;constexpr int conexprTempA = 4;/*1.正常运行,编译通过*/const int *conptrA = &tempA;const int *conptrB = &conTempA;const int *conptrC = &conexprTempA;/*2.局部变量的地址要运行时才能确认,故不能在编译期决定,编译不过*/constexpr int *conexprPtrA = &tempA;constexpr int *conexprPtrB = &conTempA;constexpr int *conexprPtrC = &conexprTempA;/*3.第一个通过,后面两个不过,因为constexpr int *所限定的是指针是常量,故不能将常量的地址赋给顶层const*/constexpr int *conexprPtrD = &g_tempA;constexpr int *conexprPtrE = &g_conTempA;constexpr int *conexprPtrF = &g_conexprTempA;/*4.局部变量的地址要运行时才能确认,故不能在编译期决定,编译不过*/constexpr const int *conexprConPtrA = &tempA;constexpr const int *conexprConPtrB = &conTempA;constexpr const int *conexprConPtrC = &conexprTempA;/*5.正常运行,编译通过*/constexpr const int *conexprConPtrD = &g_tempA;constexpr const int *conexprConPtrE = &g_conTempA;constexpr const int *conexprConPtrF = &g_conexprTempA;return 0;
}

四、对引用的修饰

代码如下:

#include <iostream>
using namespace std;int g_tempA = 4;
const int g_conTempA = 4;
constexpr int g_conexprTempA = 4;int main(void)
{int tempA = 4;const int conTempA = 4;constexpr int conexprTempA = 4;/*1.正常运行,编译通过*/const int &conptrA = tempA;const int &conptrB = conTempA;const int &conptrC = conexprTempA;/*2.有两个问题:一是引用到局部变量,不能再编译器确定;二是conexprPtrB和conexprPtrC应该为constexpr const类型,编译不过*/constexpr int &conexprPtrA = tempA;constexpr int &conexprPtrB = conTempA;constexpr int &conexprPtrC = conexprTempA;/*3.第一个编译通过,后两个不通过,原因是因为conexprPtrE和conexprPtrF应该为constexpr const类型*/constexpr int &conexprPtrD = g_tempA;constexpr int &conexprPtrE = g_conTempA;constexpr int &conexprPtrF = g_conexprTempA;/*4.正常运行,编译通过*/constexpr const int &conexprConPtrD = g_tempA;constexpr const int &conexprConPtrE = g_conTempA;constexpr const int &conexprConPtrF = g_conexprTempA;return 0;
}

简单的说constexpr所引用的对象必须在编译期就决定地址。还有一个奇葩的地方就是可以通过上例conexprPtrD来修改g_tempA的值,也就是说constexpr修饰的引用不是常量,如果要确保其实常量引用需要constexpr const来修饰。

以上是C++ 11 constexpr的简单应用,要深入学好C++,需要长期的训练,刻意练习。

C++11关键字constexpr看这篇就够了相关推荐

  1. TF卡里删掉文件后内存没变大_双11,TF卡,SD卡,读卡器如何选,看这篇就够了...

    此文章发布已经半年有余,各大厂家推出了很多新的SD卡,且SD卡组织也推出了新的标准,所以这篇文章的内容已经有些过时,还得烦请各位移步到新的文章: 黄昏百分百:TF卡,SD卡,读卡器,USB拓展坞如何选 ...

  2. 【超全汇总】学习数据结构与算法,计算机基础知识,看这篇就够了【ZT帅地】2020-3-7

    https://blog.csdn.net/m0_37907797/article/details/104029002 由于文章有点多,并且发的文章也不是一个系列一个系列发的,不过我的文章大部分都是围 ...

  3. React入门看这篇就够了

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 很多值得了解的细节. 原文:React入门看这篇就够了 作者:Random Fundebug经授权转载,版权归原作者所 ...

  4. uiautomation遍历windows所有窗口_万字长文!滑动窗口看这篇就够了!

    大家好,我是小浩.今天是小浩算法 "365刷题计划" 滑动窗口系列 - 整合篇.之前给大家讲解过一些滑动窗口的题目,但未作系统整理. 所以我就出了这个整合合集,整合工作中除了保留原 ...

  5. .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了

    本来这篇只是想简单介绍下ASP.NET Core MVC项目的(毕竟要照顾到很多新手朋友),但是转念一想不如来点猛的(考虑到急性子的朋友),让你通过本文的学习就能快速的入门ASP.NET Core.既 ...

  6. 史上最全!用Pandas读取CSV,看这篇就够了

    导读:pandas.read_csv接口用于读取CSV格式的数据文件,由于CSV文件使用非常频繁,功能强大,参数众多,因此在这里专门做详细介绍. 作者:李庆辉 来源:大数据DT(ID:hzdashuj ...

  7. 面试率 90% 的JS事件循环Event Loop,看这篇就够了!! !

    面试率 90% 的JS事件循环Event Loop,看这篇就够了!! ! 事件循环(Event Loop)大家应该并不陌生,它是前端极其重要的基础知识.在平时的讨论或者面试中也是一个非常高频的话题. ...

  8. Docker入门实战看这篇就够了(最新详细以及踩过的坑)

    Docker入门实战看这篇就够了 前言 初识 是什么 容器与虚拟机 能干什么 去哪玩 安装 先决条件 查看自己的内核 安装所需的软件包(支持devicemapper存储类型) 设置镜像的仓库 设置yu ...

  9. NDK撩妹三部曲(四)—NDK 开发如何优雅的定位 Native 异常,看这篇就够了

    NDK 开发如何优雅的定位 Native 异常,看这篇就够了 从何说起? 摘要 案例实操 aaddr2line objdump ndk-stack 1.假设我们已经通过 adb logcat 拿到了程 ...

最新文章

  1. Tomcat 部署项目的三种方法
  2. linux图片添加滤镜,PhotoFlare开源图像和照片编辑器,附在Ubuntu 18.04下的安装方法...
  3. Android使用adb命令安装应用-连接usb
  4. 6月30日云栖精选夜读:程序员技术与文艺的PK_来首届阿里巴巴研发效能嘉年华...
  5. 怎样在汉字后面加空格?
  6. BZOJ——1614: [Usaco2007 Jan]Telephone Lines架设电话线
  7. spss无法连接到本地计算机,有关IBM SPSS Statistics无法打开的几个原因,附带解决方法...
  8. 联想如何在桌面显示计算机和网络图标,联想电脑桌面图标字体变小怎么办
  9. 行为经济学_为什么所有数据科学家都应该了解行为经济学
  10. hr面试性格测试30题_HR经典面试30题
  11. 金蝶K/3 ERP 基于Citrix Access Gateway 的SSL ××× 部署方案
  12. 计算机win10无法打开小键盘,在win10中,数字小键盘开机不启动的原因是什么?...
  13. CTR---DIN原理,及deepctr组网实现DIN
  14. 家园守卫战新系统冲入海盗营地漏洞,无限赚钱
  15. CSS3-美化网页元素
  16. android 伪装 wifi,移动数据伪装wifi软件xposed手机版-手机移动数据伪装wifi模块xposedv1.4最新版_新绿资源网...
  17. 数学建模第一讲:层次分析法
  18. DES加解密的python实现
  19. 三维空间刚体运动3:欧拉角表示旋转(全面理解万向锁、RPY角和欧拉角)
  20. 如何下载指定版本(旧)的visual studio

热门文章

  1. 「网络基础」TCP/IP协议4层模型,一分钟了解下
  2. 初级Java应届生面试题(持续更新。。。)
  3. layui一行并排两个卡片面板小记
  4. 网络协议学习:通用路由封装协议GRE
  5. libstdc++.so.6
  6. 单机安装多个mysql_单机环境下安装多个MySQL服务器
  7. html表格里面怎么合并单元格的快捷键,合并单元格快捷键,教您excel怎么合并单元格快捷键...
  8. iOS 7: 如何为iPhone 5S编译64位应用
  9. ubuntu下创建管理员权限的账户
  10. Stata绘图:在图片中添加虚线网格线