c++字面值常量
constexpr 變量是編譯器驗證的編譯期就求得結果的一種變量~
一、constexpr 函數(constexpr function)指能用于常量表達式(編譯期必須求出結果有一部分const 類型的值 和constexpr類型)的函數,constexpr函數必須滿足如下介個要求:
? ? ? ?1.函數的返回類型和所有形參類型必須是字面值類型,且函數體必須只且有一條return 語句,例如:
? ? ? ? ? ? ? ? ? ?
constexpr int new_sz() {return 42;} constexpr int foo = new_sz();? ? ? ? ? ? ?編譯器能在編譯期驗證new_sz()的值,所以可以用new_sz() 初始化constexpr類型變量foo.為了執行foo的初始化語句,編譯器在編譯期把constexpr函數的調用替換成其結果值,為了能在編譯過程中隨時展開,constexpr函數隱式地指定為內聯函數.? ? ? ? ? ? 2.允許constexpr函數返回一個不是常量的值。
constexpr size_t scale(size_t cnt){return new_sz() * cnt;} //new_sz()是一個零時量,不是constexpr當scale函數的實參是常量表達式時,那么它的返回值是常量表達式;反之則不然:
int arr[scale(2)]; //正確;scale(2)是常量表達式 int i = 2; int a2[scale(i)]; //錯誤,scale(i)不是常量表達式? ? ? ? 如上所示,當我們給scale()函數傳入一個形如字面值2的常量表達式時,它的返回類型是常量表達式。此時,編譯器用相應的結果值替換對scale函數的調用。反之,當我們用一個非常量的表達式調用scale函數,比如int類型的對象i,則返回值是一個非常量表達式。當把scale函數用在需要常量表達式的上下文中時,則編譯器負責檢查函數的結果是否符合要求。如果恰好不是常量表達式,編譯器將會發出錯誤信息。(我用g++運行參數是非constexpr變量的constexpr函數,結果竟然可以作為常量使用)
constexpr 調用必須滿足如下條件:
? ? (1)變量初值必須用constexpr表達式初始化,或者是編譯器可以確定值的const值初始化
? ? ? (2)constexpr用函數值初始化必須滿足:
? ? ? ? ? ?1.函數必須返回值是constexpr
? ? ? ? ? ?2.必須在調用前全部定義,(涉及函數相互調用那么全部都為constexpr,主函數前可以聲明調用,但是必須所有定義都在main()調用之前)
? ? ? ? ? ? ? 3.用函數值作為初值,不能是const函數,const函數不是constexpr函數,因為在運行時候才能求值。
? ? ? ? ? ? ?4.只有字面值類型才能定義為constexpr,字面值類型包括:算術類型,指針,引用,其它不是
? ? ? ? ? ? 5.c++ primer上說,如果constexpr函數作為數組的個數參數,例如 int a[f()],那么f()必須是返回constexpr 類型,且參數類型也是constexpr類型才可以,但是我試了下,參數類型不是constexpr類型也可以,代碼如下:
#include <iostream> #include <string> using namespace std;constexpr int f(int w); constexpr int get_value(int v){ //這里參數類型不是constexpr intreturn v; }int main() {int k = 6;int array[get_value(k)] = {1,1,1}; //參數類型不是constexpr類型依然成功cout << "printing the array:" << endl;for (auto i : array)cout << i <<endl; //成功打印出數組return 0; }打印結果如下:
r@r-Sys:~/now$ ./123 printing the array: 1 1 1 0 0 0?
總結
- 上一篇: 为什么有些美国人名字仅仅只是两个英文字母
- 下一篇: constexpr函数