C++11新标准:constexpr关键字
一、constexpr意义
将变量声明为constexpr类型以便由编译器来验证变量是否是一个常量表达式(不会改变,在编译过程中就能得到计算结果的表达式)。是一种比const更强的约束,这样可以得到更好的效率和安全性。
二、constexpr用法
1.修饰函数
/*1.如果size在编译时能确定,那么返回值就可以是constexpr,编译通过*/
constexpr int getSizeA(int size)
{
return *size;
}
/*2.编译通过,有告警:在constexpr中定义变量*/
constexpr int getSizeB(int size)
{
int index = ;
return ;
}
/*3.编译通过,有告警:在constexpr中定义变量(这个有点迷糊)*/
constexpr int getSizeC(int size)
{
constexpr int index = ;
return ;
}
/*4.编译通过,有告警:使用了if语句(使用switch也会告警)*/
constexpr int getSizeD(int size)
{
if()
{}
return ;
}
/*5.定义变量并且没有初始化,编译不过*/
constexpr int getSizeE(int size)
{
int index;
return ;
}
/*6.rand()为运行期函数,不能在编译期确定,编译不过*/
constexpr int getSizeF(int size)
{
return *rand();
}
/*7.使用了for,编译不过*/
constexpr int getSizeG(int size)
{
for(;;)
{}
return *rand();
}
总结:constexpr修饰的函数,不能依赖任何运行期的信息,不要定义任何变量常量,并且必须尽量简单,要不就会编译不过或告警(坑)。
2.修饰类型
int tempA;
cin>>tempA; const int ctempA = ;
const int ctempB = tempA;
/*1.可以再编译器确定,编译通过*/
constexpr int conexprA = ;
constexpr int conexprB = conexprA + ;
constexpr int conexprC = getSizeA(conexprA);
constexpr int conexprD = ctempA;
/*2.不能在编译期决定,编译不过*/
constexpr int conexprE = tempA;
constexpr int conexprF = ctempB;
总结:constexpr修饰的常量必须在编译期确定值,上面的例子也体现出了和const之间的差别。const既可以在编译期确定如ctempA,也可以在运行期确定如ctempB,使用范围更广。还有一点constexpr只能修饰字面值类型如算数类型、引用类型、指针以及后面介绍的字面值常量类。
3.修饰指针
int g_tempA = ;
const int g_conTempA = ;
constexpr int g_conexprTempA = ; int main(void)
{
int tempA = ;
const int conTempA = ;
constexpr int conexprTempA = ; /*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 ;
}
总结:constexpr指针不能用局部变量赋值,const指针可以;constexpr指针里是顶层const,即指针是常量,而不是所指向的类型是常量,如果要指向的类型也为常量,要用constexpr const来修饰。
4.修饰引用
int g_tempA = ;
const int g_conTempA = ;
constexpr int g_conexprTempA = ; int main(void)
{
int tempA = ;
const int conTempA = ;
constexpr int conexprTempA = ;
/*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 ;
}
总结:简单的说constexpr所引用的对象必须在编译期就决定地址。还有一个奇葩的地方就是可以通过上例conexprPtrD来修改g_tempA的值,也就是说constexpr修饰的引用不是常量,如果要确保其实常量引用需要constexpr const来修饰。
5.修饰类(未完待续)
C++11新标准:constexpr关键字的更多相关文章
- C++11新标准:nullptr关键字
一.nullptr的意义 1.NULL在C中的定义 #define NULL (void*)0 2.NULL在C++中的定义 #ifndef NULL #ifdef __cplusplus #defi ...
- C++11新标准:decltype关键字
一.decltype意义 有时我们希望从表达式的类型推断出要定义的变量类型,但是不想用该表达式的值初始化变量(如果要初始化就用auto了).为了满足这一需求,C++11新标准引入了decltype类型 ...
- C++11新标准:auto关键字
一.auto意义 编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚地知道表达式的类型,然后要做到这一点并非那么容易.为了解决这个问题,C++11新标准引入了auto类型说明符,用它就能 ...
- C++11新标准学习
<深入理解C++11:C++11新特性解析与应用> <华章科技:深入理解C++11:C++11新特性解析与应用>一共8章:第1章从设计思维和应用范畴两个维度对C++11新标准中 ...
- c++11新标准for循环和lambda表达式
:first-child { margin-top: 0px; } .markdown-preview:not([data-use-github-style]) h1, .markdown-previ ...
- 关注C++细节——C++11新标准之decltype的使用注意
c++11新特性--decltype decltype是C++11加入的一个新的keyword,目的是选择并返回操作数的数据类型,重要的是,在此过程中编译器分析表达式并得到它的类型,却不实际计算表达式 ...
- 基于c++11新标准开发一个支持多线程高并发的网络库
背景 新的c++11标准出后,c++语法得到了非常多的扩展,比起以往不论什么时候都要灵活和高效,提高了程序编码的效率,为软件开发者节省了不少的时间. 之前我也写过基于ACE的网络server框架,但A ...
- C++11新标准
1. 新类型 long long和unsigned long long: char16_t 和 char32_t: 新增原始字符串: 2. 统一的初始化 C++11扩大了用大括号括起的列表(初始化列表 ...
- C++ 11新标准实现POJ No.1002-487-3279
487-3279(重复的电话号码查询)(标签:优先队列,哈希表) 题目描述 企业喜欢用容易被记住的电话号码.让电话号码容易被记住的一个办法是将它写成一个容易记住的单词或者短语.例如,你需要给滑铁卢大学 ...
随机推荐
- LeetCode Maximum Length of Pair Chain
原题链接在这里:https://leetcode.com/problems/maximum-length-of-pair-chain/description/ 题目: You are given n ...
- shell实现文件内容查询如输入姓名结果显示电话号码等信息
#!/bin/awk -f BEGIN{FS=","; if(ARGC>2){name=ARGV[1];delete ARGV[1]} else{ echo "pl ...
- Unity3d-WWW实现图片资源显示以及保存和本地加载
本文固定连接:http://blog.csdn.net/u013108312/article/details/52712844 WWW实现图片资源显示以及保存和本地加载 using UnityEngi ...
- Visualforce Page CSS样式
Salesforce Page开发者文档:https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_stylin ...
- ECS Windows系统使用自带监视器查看IIS并发连接数
问题现象 ECS Windows系统如何查看IIS并发连接数? 解决方案 1.运行-->输入“perfmon.msc” . 2.在“系统监视器”图表区域里点击右键,然后点“添加计数器”. 3.在 ...
- 第十四章 Spring MVC的工作机制与设计模式(待续)
Spring MVC的总体设计 Control设计 Model设计 View设计 框架设计的思考 设计模式解析之模版模式
- 【Android 多媒体应用】使用MediaCodec解码使用SurfaceView显示视频
1.MainActivity.java import android.app.Activity; import android.os.Bundle; import android.os.Environ ...
- cygwin选择安装包选项搭建NDK开发环境/配置cygwin的root权限
9.Search是可以输入你要下载的包的名称,能够快速筛选出你要下载的包.那四个单选按钮是选择下边树的样式,默认就行,不用动.View默认是Category,建议改成full显示全部包再查,省的一些包 ...
- Java was started but returned exit code=13 问题解决
我在安装完jdk后,也对环境进行了配置,且环境的配置是没有问题的.最后我下载了eclipse,然后打开之后就发现了以下图所示的错误: Java was started but returned exi ...
- maven 配置说明
1.坐标 1.1 每一jar文件都有一个唯一坐标.通过坐标可以精确确定是哪个jar 1.2 坐标组成 1.2.1 Group ID : 公司名.公司网址倒写 1.2.2 Artifact ID : 项 ...