博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++的constexpr
阅读量:4093 次
发布时间:2019-05-25

本文共 1570 字,大约阅读时间需要 5 分钟。

一、定义

constexpr是C++11开始提出的关键字,其意义与14版本有一些区别。

C++11中的constexpr指定的函数返回值和参数必须是字面值,而且必须有且只有一行return代码,这给函数的设计者带来了更多的限制。而C++14中只要保证返回值和参数是字面值就行了,函数体中可以加入更多的语句,方便了更灵活的计算。

很多人都把constexpr和const相比较。其实,const并不能代表“常量”,它仅仅是对变量的一个修饰,告诉编译器这个变量只能被初始化,且不能被直接修改(实际上可以通过堆栈溢出等方式修改)。而这个变量的值,可以在运行时,也可以在编译时指定。constexpr可以用来修饰变量、函数、构造函数。一旦以上任何元素被constexpr修饰,那么等于说是告诉编译器 “请大胆地将我看成编译时就能得出常量值的表达式去优化我”。

二、使用

constexpr所修饰的变量一定是编译期可求值的,所修饰的函数在其所有参数都是constexpr时,一定会返回constexpr。

constexpr  int foo( int i) {	 return i + 5; } int main() {	 constexpr  int  a = foo(1); // ok	 constexpr  int  b = foo(cin.get()); // !error	 constexpr  int  c = a * 2 + 1; // ok  }

以下编译失败,对于funcTest,胆小的编译器并没有足够的胆量去做编译期优化,哪怕函数体就一句return 字面值;

const int funcTest() {	 return 10; } int main() {	 int arr[funcTest()];}//error : 函数调用在常量表达式中必须具有常量值

 修改后,编译通过,编译期大胆地将funcTest()做了优化,在编译期就确定了func计算出的值10而无需等到运行时再去计算。

constexpr int funcTest() {	 return 10; } int main() {	 int arr[funcTest()];}

另一个例子

template
class C {}; constexpr int FivePlus(int x) { return 5 + x; } void f(const int x) { C
c1; // Error: x is not compile-time evaluable. C
c2; // OK }

 constexpr还能用于修饰类的构造函数,即保证如果提供给该构造函数的参数都是constexpr,那么产生的对象中的所有成员都会是constexpr,该对象也就是constexpr对象了,可用于各种只能使用constexpr的场合。注意,constexpr构造函数必须有一个空的函数体,即所有成员变量的初始化都放到初始化列表中。

struct  A {	 constexpr  A(int  xx, int  yy) : x(xx), y(yy) {}	 int  x, y; }; constexpr  A a(1, 2); enum { SIZE_X = a.x, SIZE_Y = a.y };

三、总结

  1. 是一种很强的约束,更好地保证程序的正确语义不被破坏。
  2. 编译器可以在编译期对constexpr的代码进行非常大的优化,比如将用到的constexpr表达式都直接替换成最终结果等。
  3. 相比宏来说,没有额外的开销,但更安全可靠。

参考:

 

 

转载地址:http://ljiii.baihongyu.com/

你可能感兴趣的文章
GitHub 上的一个开源项目,可快速生成一款属于自己的手写字体!
查看>>
早知道这些免费 API,我就可以不用到处爬数据了!
查看>>
Python 字符串加密(MD5、base64、sha1),base64解密
查看>>
python 通过SSHTunnelForwarder隧道连接redis
查看>>
jmeter后置处理器保存数据到本地,并通过前置处理器获取数据
查看>>
jmeter前置处理器调用java方法,以md5加密为例
查看>>
使用flask框架编写简单的mock平台
查看>>
小程序开发-环境搭建
查看>>
小程序开发-导航栏
查看>>
Elasticsearch非集群单节点安装教程
查看>>
Filebeat安装教程
查看>>
Logstash安装教程
查看>>
Kibana安装教程
查看>>
telnet命令介绍
查看>>
curl命令介绍
查看>>
ELK日志分析系统
查看>>
Linux常用命令
查看>>
springboot下配置logback
查看>>
Springboot下使用Elasticsearch教程
查看>>
Springboot之Kafka
查看>>