為了使函式獲取編譯時計算的能力,你必須指定constexpr關鍵字到這個函式。
constexpr int multiply (int x, int y)// 將在編譯時計算
const int val = multiply( 10, 10 );
除了編譯時計算的效能優化,constexpr的另外乙個優勢是,它允許函式被應用在以前呼叫巨集的所有場合。例如,你想要乙個計算陣列size的函式,size是10的倍數。如果不用constexpr,你需要建立乙個巨集或者使用模板,因為你不能用函式的返回值去宣告陣列的大小。但是用constexpr,你就可以呼叫乙個constexpr函式去宣告乙個陣列。
constexpr int getdefaultarraysize (int multiplier)int my_array[ getdefaultarraysize( 3 ) ];
乙個constexpr有一些必須遵循的嚴格要求:
注意遞迴並不受限制。但只允許乙個返回語句,那如何實現遞迴呢?可以使用三元運算子(?:)。例如,計算n的階乘:
constexpr int factorial (int n)
現在你可以使用factorial(2),編譯器將在編譯時計算這個值,這種方式執行更巧妙的計算,與內聯截然不同。你無法內聯乙個遞迴函式。
constexpr函式還有那些特點?
乙個constexpr函式,只允許包含一行可執行**。但允許包含typedefs、 using declaration && directives、靜態斷言等。
乙個宣告為constexpr的函式同樣可以在執行時被呼叫,當這個函式的引數是非常量的:
int n;cin >> n;
factorial( n );
這意味著你不需要分別寫執行時和編譯時的函式。
假如你有乙個circle類:
class circledouble getarea () const
private:
int _x;
int _y;
int _radius;
};
你希望在編譯期構造乙個circle接著算出他的面積。
constexpr circle c( 0, 0, 10 );constexpr double area = c.getarea();
事實證明你可以給circle類做一些小的修改以完成這件事。首先,我們需要將建構函式宣告為constexpr,接著我們需要將getarea函式宣告為constexpr。將建構函式宣告為constexpr則執行建構函式在編譯期執行,只要這個建構函式的引數為常量,且建構函式僅僅包含成員變數的constexpr構造(所以預設構造可以看成constexpr,只要成員變數都有constexpr構造)。
class circleconstexpr double getarea ()
private:
int _x;
int _y;
int _radius;
};
假如你將乙個成員函式標記為constexpr,則順帶也將它標記為了const。如果你將乙個變數標記為constexpr,則同樣它是const的。但相反並不成立,乙個const的變數或函式,並不是constexpr的。
到這裡我們講到的constexpr功能都可以通過模板元程式設計實現。但constexpr支援的一項能力是可以計算浮點型的資料。因為double和float不是有效的模板引數,你不可以輕易的通過模板編譯期計算浮點數的值。而constexpr允許編譯期計算浮點型資料。
原文部落格:
常量表示式
字面值 是乙個不能改變的值,如數字 字元 字串等。單引號內的是字元字面值,雙引號內的是字串字面值。字面值型別 literal type 算數型別 引用和指標等。常量表示式 const experssion 是指 1 值不會改變 並且 2 在編譯過程就能得到計算結果的表示式。字面量屬於常量表示式,用常...
解析常量表示式
define crt secure no warnings include include include intisnum char ch void eatspace char str char roundbmatch char str,int pindex double getnum char ...
C constexpr 常量表示式
在c 11中引入了constexpr關鍵字.意思是常量表示式,詳細來說就是在編譯期可求值的表示式.可以修飾表示式,函式,建構函式,類等 可以讓編譯器做出尺度更大的優化.這個關鍵字是為了解決以前的const關鍵字帶來的一些問題,其實在 實戰中const顯然是只有readonly唯讀這個概念,其在很多場...