一、常量表達式:是指值不會改變並且在編譯過程就能得到計算結果的表達式。一個對象是不是常量表達式是由它的數據類型和初始值共同決定。
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、再介紹下字面值常量類
數據成員是字面值類型的聚合類是字面值常量類。符合下述要求的類也是字面值常量類:
- 數據成員都是字面值類型
- 類必須至少含有一個constexpr構造函數,這樣的函數必須符合constexpr函數的所有要求,他們是隱式const的。
- 如果一個數據成員含有類內初始值,則內置數據成員的初始值必須是一條常量表達式;如果成員屬於某種類類型,則初始值必須使用成員自己的constexpr構造函數。
- 類必須使用析構函數的默認定義,該成員負責銷毀類的對象。
雖然構造函數不能是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++包括兩種枚舉:限定作用域和不限定作用域的。
