1. 程式人生 > >常量表達式和constexpr(c++11)

常量表達式和constexpr(c++11)

常量表達式

  常量表達式是指值不會改變且在編譯階段就能得到計算結果的表示式:

const int max_files = 20;    //是常量表達式
const int limit = max_file + 1;        //是常量表達式
int staff_size = 27;    //不是常量表達式
const int sz = get_size();    //不是常量表達式,儘管sz本身是一個常量,但是它的值直到程式執行時才能獲得

constexpr(c++11)

  c++11允許將變數宣告為constexpr型別讓編譯器來驗證變數是否為一個常量表達式。宣告為constexpr的變數一定是一個常量,並且必須用常量表達式來初始化:

constexpr int mf = 20;
constexpr int limit = mf + 1;
constexpr int sz = get_size();    //只有當get_size()是一個constexpr函式時才是正確的宣告

const變數 和 constexpr 變數之間的主要區別

1.const 變數的初始化可以延遲到執行時,而 constexpr 變數必須在編譯時進行初始化:

const int sz = get_size();    //正確的宣告,但是sz不是常量表達式
constexpr int sz = get_size();    //只有當get_size()是一個constexpr函式時才是正確的宣告

 2.constexpr宣告中如果定義了一個指標,限定符constexpr只對指標有效,與指標所指的物件無關:

const int* p = nullptr;    //p是一個指向整型常量的指標
constexpr int* q = nullptr;        //q是一個指向整型的常量指標
constexpr const int* r = nullptr;        //r是一個指向整型常量的常量指標

constexpr函式

  用限定符constexpr修飾函式,使之用於常量表達式中,constexpr函式有這麼幾個特性:

1.函式的返回型別和所有的形參型別都是字面值型別

2.函式體中只有一條語句,而且只能是一條return語句(但其實也是可以包含其他語句的,只要這些語句在程式執行時不執行任何操作就行,如:空語句、類型別名、using宣告)

constexpr int new_sz()
{
    return 43;
}

3.constexpr函式被隱式地指定為行內函數

4.編譯器其實也允許constexpr函式的返回值和形參不是字面值:

constexpr int get_size(int a)
{
    return a;
}

int main()
{
    int size = 5;
    int y = get_size(size);    //正確,因為y是非constexpr的,可以不要求get_size是constexpr的
    constexpr int z = get_size(size);        //錯誤!!!

    int arr1[get_size(5)];    //正確
    int arr2[get_size(size)];    //錯誤,陣列的大小要求是常量表達式

    return 0;
}

5.行內函數和constexpr函式可以在程式中多次定義,所以一般定義在標頭檔案中:

你可以在a.h裡定義
inline int fun()
{
  return 1;
}

在 b.h裡定義
inline int fun()
{
  return 100;
}

因為inline函式編譯時需要直接插入函式程式碼,所以不能使用extern,每個cpp原始檔中必須包含其定義程式碼(不是宣告) 所以"行內函數有可能在程式中定義不止一次,"就是指在每個呼叫inline函式的cpp原始檔中都要有inline函式的定義,所以把inline函式定義在標頭檔案中,需要時include就可以了;