C++之constexpr

2019/08/15 14:51
阅读数 27

一、常量表达式:是指值不会改变并且在编译过程就能得到计算结果的表达式。一个对象是不是常量表达式是由它的数据类型和初始值共同决定。

1 int staff_size = 27;//虽然初始值是字面值常量,但是它的数据类型只是普通int。
2 const int sz = get_size(); //虽然sz本身是常量,但是它的具体值直到运行时才能获取到所以也不是常量表达式

 

二、constexpr变量

  将变量声明成为constexpr类型,声明为constexpr类型的变量一定是一个常量,且必须使用常量表达式初始化。

1 constexpr int mf = 20;    //20是常量表达式
2 constexpr int sz = size();  //只有当size()是一个constexpr函数时,才是一个正确的声明语句。

 

三、constexpr函数

  constexpr函数可以用于初始化constexpr变量,其函数的返回类型以及所有形参的类型都是字面值类型且函数体中有且只有一条return语句。且constexpr函数和被隐式的指定为内联函数。

1 //编译器在程序编译时可以验证new_sz返回的是常量表达式,所以可以用new_sz的返回值初始化constexpr变量foo
2 constexpr int new_sz() {return 42;}
3 constexpr int foo = new_sz(); //foo是一个常量表达式

 

  另外我们允许constexpr函数的返回值并非一个常量:如果实参是常量表达式,那么函数返回值也是常量表达式

 1 //当scale的实参是常量表达式时,其返回值也是常量表达式 2 constexpr size_t scale(size_t cnt){return new_sz() * cnt} 

 四、再来介绍下字面值类型

算术类型、引用、指针、字面值常量类、枚举类型都是字面值类型。而其他自定义类、IO库、STL库都不属于字面值类型。尽管指针和引用能被定义为constexpr,但是他们的初始值要受到严格限制。一个constexpr指针的初始值必须是nullptr或0,或者时存储于某个固定地址中的对象:比如全局变量或者局部静态变量

  1、介绍下指针这个字面值类型:限定符constexpr只对指针有效,与指针所指对象无关。

 1 const int *p = nullptr;  //p是一个指向整型常量的指针
 2 constexpr int *p = nullptr;//p是一个指向整数的常量指针
 3 //在于constexpr把它所定义的对象置成了鼎城const,与下面这个一样了。
 4 int *const p ; //p是一个常量指针,指向整数
 5 //既然ocnstexpr是常量指针,那么它既能指向常量也能指向非常量。
 6 
 7 int j =0; 
 8 constexptr int i = 0;
 9 
10 constexpr const int *p = i; //p是常量指针,指向整型常量
11 constexpr int *p1 = j;     //p1也是常量指针,指向整数j
12 
13 //注意:i和j必须要定义在函数体之外,即必须是存储在某个固定地址的对象。

 

  2、再介绍下字面值常量类

数据成员是字面值类型的聚合类是字面值常量类。符合下述要求的类也是字面值常量类:

  1. 数据成员都是字面值类型
  2. 类必须至少含有一个constexpr构造函数,这样的函数必须符合constexpr函数的所有要求,他们是隐式const的
  3. 如果一个数据成员含有类内初始值,则内置数据成员的初始值必须是一条常量表达式;如果成员属于某种类类型,则初始值必须使用成员自己的constexpr构造函数
  4. 类必须使用析构函数的默认定义,该成员负责销毁类的对象。

虽然构造函数不能是const的(因为当我们创建类的一个const对象时,只有构造函数完成初始化过程,对象才真正可以取得常量属性),但是字面值常量类的构造函数可以是constexpr.

 1 class Debug{
 2 public:
 3 //constexpr的构造函数必须初始化所有数据成员,初始值使用constexpr构造函数或者是一条常量表达式。
 4      constexpr Debug (bool b = ture):hw(b),io(b),other(b){}
 5      constexpr Debug(bool h,bool i,bool o):
 6                                                       hw(h),io(i),other(o){}
 7      cosntexpr bool any() {return hw||io||other;}
 8      void set_io(bool b) { io = b;}
 9      void set_hw(bool b) { hw = b;}
10      void set_other(bool b){ other = b;}
11 private:
12      bool hw;
13      bool io;
14      bool other;
15 
16 }

 

  3.再介绍下枚举类型

C++包括两种枚举:限定作用域和不限定作用域的。

展开阅读全文
c++
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部