C 11新特性之常量表示式 constexpr

2021-08-20 22:29:46 字數 2218 閱讀 9460

在c++11中引入了乙個新的關鍵字「constexpr」,用來修飾乙個函式或者變數使其變成乙個常量表示式或值。比如下面的**將函式getconstvalue變成乙個常量表示式,並用這個常量表示式宣告乙個陣列:

constexpr int getconstvalue() ;

int a[getconstvalue()];

有了constexpr關鍵字,編譯器就可以在編譯時期計算函式getconstvalue()的值,使其可以被看作是乙個編譯期常量。此時,函式getconstvalue()被稱為"常量表示式函式"。

並不是任何乙個函式加上constexpr關鍵字後都可以成為「常量表示式函式」。常量表示式函式必須滿足以下幾點要求:

1. 函式體只有單一的return語句。(一些不會產生實際**的語句在函式中可以使用,如static_assert, using, typedef等)

2. 函式必須有返回值(即不能式void函式)

3. 在被使用之前必須已有定義。

4. return返回語句表示式中不能使用非常量表示式的函式,全域性資料,且必須是乙個常量表示式。

常量表示式值是乙個被constexpr修飾的變數,並且這個變數必須被乙個常量表示式初始化。比如:

constexpr int a = 1;  //常量表示式值

cosnt int b = 1; //常量

用cosntexpr修飾的變數a和用const修飾的變數b,它們有什麼區別呢?在大多數情況下,它們沒有區別,不過有一點要注意,如果變數b在全域性名字空間中,編譯器就會為它而產生資料,對於a,編譯器則可以選擇不為它產生資料。

const並未區分出編譯期常量和執行期常量

constexpr限定在了編譯期常量

然後我想對修飾函式多說兩句,那就是constexpr修飾的函式,返回值不一定是編譯期常量。#it is not a bug, it is a feature.#

#include #include using namespace std;

constexpr int foo(int i)

int main()

所以,對於constexpr需要兩方面看待。

constexpr修飾的函式,簡單的來說,如果其傳入的引數可以在編譯時期計算出來,那麼這個函式就會產生編譯時期的值。但是,傳入的引數如果不能在編譯時期計算出來,那麼constexpr修飾的函式就和普通函式一樣了。不過,我們不必因此而寫兩個版本,所以如果函式體適用於constexpr函式的條件,可以盡量加上constexpr。

而檢測constexpr函式是否產生編譯時期值的方法很簡單,就是利用std::array需要編譯期常值才能編譯通過的小技巧。這樣的話,即可檢測你所寫的函式是否真的產生編譯期常值了。

對於自定義型別的資料,constexpr不能用來修飾自定義型別的定義的,形如下面的**是無法通過編譯的:

constexpr class base //constexpr不能修飾base的定義,編譯錯誤
正確的做法是自定義常量建構函式:

class base

int m_i;

};constexpr base ba = ;

需要注意的是,常量建構函式的定義也有使用上的約束:

1. 函式體必須為空

2. 初始化列表只能由常量表示式賦值。

在c++11標準中,不允許常量表示式作用於virtual的成員函式,因為virtual表示的是執行時的行為,這與constexpr「可以在編譯時期進行計算」的意義是衝突的。「在編譯時期進行計算」是對編譯器的乙個建議,c++11標準並沒有強制要求編譯器一定要在編譯時期對常量表示式函式進行計算。

另外,constexpr也可用於模板函式,c++11標準規定,對於乙個宣告為常量表示式的模板函式,如果它的某乙個例項化結果不滿足常量表示式的需求的話,constexpr會被自動忽略而變成乙個普通函式。比如下面的**:

class base ;

templateconstexpr t getvalue(t t)

void main()

C 11之常量表示式

2013 09 17 c 11有一些這樣的改善,這種改善保證寫出的 比以往任何時候的執行效率都要好。這種改善之一就是生成常量表示式,允許程式利用編譯時的計算能力。假如你熟悉模板元程式設計,你將發現constexpr使這一切變得更加簡單。假如你不知道模板元程式設計,也沒什麼。constexpr使我們很...

c 11 常量表示式

define crt secure no warnings include include include include 常量表示式主要是允許一些計算發生在編譯時,即發生在 編譯而不是執行的時候。這是很大的優化 假如有些事情可以在編譯時做,它將只做一次,而不是每次程式執行時都計算。constexp...

c 11 常量表示式

define crt secure no warnings include include include include 常量表示式主要是允許一些計算發生在編譯時,即發生在 編譯而不是執行的時候。這是很大的優化 假如有些事情可以在編譯時做,它將只做一次,而不是每次程式執行時都計算。constexp...