C++11 constexpr常量表达式
常量表达式函数
要求:
- 函数体内只有单一的return返回语句
例如:
constexpr int data()
{
const int i=1; //含有除了return以外的语句
return i;
}
在c++11中是无法通过编译的。
但使用不会产生实际代码的语句是可以的,例如static_assert()
2. 函数必须返回值
例如constexpr void f(){}无法通过编译的,因为无法获得常量的常量表达式是不被认可的。
3. 在使用前必须已有定义
constexpr int f();
constexpr int c=f(); //无法通过编译
constexpr int f(){return 1;}
- return返回语句表达式中不能使用非常量表达式的函数、全局数据,且必须是一个常量表达式。
const int e(){return 1;}
constexpr int g(){return e();} //编译错误,使用了非常量表达式的函数
常量表达式值
const int i=1;
constexpr int j=1;
两者在大多数情况下没有区别,但如果i在全局名称空间中,编译器一定会为i产生数据。而对于j,如果不是有代码显式地使用了它的地址,编译器可以选择不为它生成数据,而仅将其当作编译时期的值。
在C++11中constexpr是不能用于自定义类型的,例如:
constexpr struct MyType{int i;}
constexpr MyType mt={0};
将无法通过编译。正确的做法是,定义自定义常量构造函数:
struct MyType
{
constexpr MyType(int x):i(x){}
int i;
};
constexpr MyType mt = { 0 };
常量表达式的构造函数也有使用上的约束:
- 函数体必须为空
- 初始化列表只能由常量表达式来赋值。
此外,在C++11中,不允许常量表达式作用于virtual的成员函数。vitual是运行时的行为,与编译期计算的constexpr的意义是冲突的。
常量表达式的构造函数也可以用于非常量表达式中的类型构造,且无法重写。
其他应用
模板函数
常量表达式是可以用于模板函数的,不过由于模板中类型的不确定性,所以模板函数是否会被实例化为一个能够满足编译时常量性的版本通常也是未知的。C++11标准规定:当声明为常量表达式的模板函数后,而某个该模板函数的实例化结果不满足常量表达式的需求的话,constexpr会被自动忽略。该实例化后的函数将成为一个普通函数。
例如:
struct NotLiteral
{
NotLiteral(){i=5;}
int i;
};
NotListeral nl;
template<class T>
constexpr T ConstExp(T t)
{
return t;
}
void g()
{
NotLiteral nl;
NotLiteral nl1=ConstExp(nl);
constexpr NotLiteral nl2=ConstExp(nl); //无法编译
constexpr int a=ConstExp(1); //OK
}
代码中NotLiteral不是一个定义了常量表达式构造函数的类型,因此不能够声明为常量表达式值。而模板函数ConstExp一旦以NotLiteral为参数的话,那么其constexpr关键字将被忽略。
递归
常量表达式支持至少512层的递归,可以在编译期充当“计算器”。
constexpr int Fibonacci(int n)
{
return (n == 1) ? 1 : ((n == 2) ? 2 : Fibonacci(n - 1) + Fibonacci(n - 2));
}
Fibonacci(12);
然而并不是使用了constexpr,编译器就一定会在编译期间对常量表达式函数进行值计算。标准只是定义了可以用于编译时进行值计算的常量表达式的定义,却没有强制要求编译器一定在编译时进行值计算。(经反汇编,上述代码在vs2017debug下未在编译期计算出结果)所以编译器通过一些手段绕过代码的语法,仍然做运行时的调用,这样也是符合C++11的。
内容摘自《深入理解C++11》
C++11 constexpr常量表达式的更多相关文章
- C++11特性——变量部分(using类型别名、constexpr常量表达式、auto类型推断、nullptr空指针等)
#include <iostream> using namespace std; int main() { using cullptr = const unsigned long long ...
- C++11常量表达式
[C++11之常量表达式] 关键字:constexpr: 中文学名:常量表达式. constexpr用于把运行期计算放置在编译期. 使用constexpr有3个限制: 1.函数中只能有一个return ...
- 常量表达式和constexpr(c++11)
常量表达式 常量表达式是指值不会改变且在编译阶段就能得到计算结果的表达式(两点要求) ; //是常量表达式 ; //是常量表达式 "; const int siz=s.size(); //不 ...
- constexpr与常量表达式(c++11标准)
关键字 constexpr 是C++11中引入的关键字,是指值不会改变并且在编译过程中就得到计算结果的表达式.(运行中得到结果的不能成为常量表达式,比如变量). 声明为constexpr的变量一定是一 ...
- C++常量表达式、const、constexpr(C++11新增)的区别
常量表达式是指值不会改变且在编译过程中就能够得到计算结果的表达式,能在编译时求值的表达式. 程序先编译再运行: 在编译阶段, 编译器将在编译过程中把用到该常量的地方都全都替换为 常量的值. 但是常量 ...
- constexpr和常量表达式
常量表达式:值不会改变并且在编译过程就能得到计算结果的表达式. 字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式. 一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同 ...
- constexpr和常量表达式的注意事项
1.常量表达式,是指其值不可改变,且在编译阶段就已经得出计算结果的表达式,例如字面值就是常量表达式. 2.判断是否是常量表达式,要关注数据类型是否是const类型,初始值是否是在编译阶段就得到的. 3 ...
- 第8课 常量表达式(constexpr)
一. const 和constexpr的区别 (一)修饰变量时,const为“运行期常量”,即运行期数据是只读的.而constexpr为“编译期”常量,这是const无法保证的.两者都是对象和函数接口 ...
- c++11 常量表达式
c++11 常量表达式 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #inclu ...
随机推荐
- 基于python的发送邮件案例
#coding:utf-8 #强制使用utf-8编码格式 import smtplib #加载smtplib模块 from email.mime.text import MIMEText from e ...
- terminal、Shell、tty和console
最早的电脑有带很多开关和指示灯的面板——console(概念来自管风琴),一台电脑通常一个Console,化为主机一部分,和CPU共享机柜. 一台大型主机往往支持多用户,每个用户使用的终端——term ...
- iso系统镜像刻录到光盘和U盘
使用UltraISO刻录 刻录U盘,点击文件,打开,选择镜像 启动,写入硬盘镜像选择U盘即可 刻录光盘 工具,刻录光盘映像,选择镜像,需要先插入光盘刻录机(有些电脑可能自带光驱盘,且有刻录功能,那么我 ...
- icomoon:生成字体图标的方法并应用
字体图标任意缩放不会失真,也大大减少请求数量,非常好用. 在线生成工具:https://icomoon.io/app/#/select 在线SVG图库(阿里), 用于导入:http://www.ic ...
- MVC Ajax.BeginForm 提交上传图片
吃水不忘挖井人,如果对你有帮助,请说声谢谢.如果你要转载,请注明出处.谢谢! 异步提交时,出现图片不能上传. 起初我定格在 System.Web.Mvc 中.查询源码时,也是没有问题的.那问题出现 ...
- Hadoop-HBASE 热添加新节点
Hadoop-HBASE 热添加新节点 环境:192.168.137.101 hd1192.168.137.102 hd2192.168.137.103 hd3192.168.137.104 hd4四 ...
- Linux系统目录权限chmod误操作权限修复方法
Linux中,如果意外误操作将/目录权限批量设置,比如chmod -R 777 / ,系统中的大部分服务以及命令将无法使用,这时候可以通过系统自带的getfacl命令来拷贝和还原系统权限,若是其他系统 ...
- linux--切换ipython解释器到python3
Ipython修改为python3解释器: which ipython --得到路径 cat 路径--查看执行的解释器版本 sudo gedit 路径--修改解释器版本为python3 保存即可,保存 ...
- buffers和cached的区别
原文:https://www.cnblogs.com/kevingrace/p/5991604.html buffers和cached解释 ============================== ...
- pj2--图书管理系统
这一次做得是图书管理系统. 下面是功能框图 下面是流程图 实际在做这个项目的时候根据相应的实际情况对功能流程等等做了一些小小的改变. 下面是一些值得记一笔的地方. 1.借用系统自带的导航控件(Bind ...