constexpr 變數

宣告為 constexpr 的變數隱式為 const,其值可用作常量表示式。

#define 的比較

constexpr 是基於 #define 的編譯時表示式的型別安全替代品。使用 constexpr,編譯時計算的表示式將替換為結果。例如:

Version >= C++ 11

int main()
{
   constexpr int N = 10 + 2;
   cout << N;
}

將產生以下程式碼:

cout << 12;

基於前處理器的編譯時巨集將是不同的。考慮:

#define N 10 + 2

int main()
{
    cout << N;
}

將產生:

cout << 10 + 2;

這顯然會轉換為 cout << 10 + 2;。但是,編譯器必須做更多的工作。此外,如果使用不正確,也會產生問題。

例如(使用 #define):

cout << N * 2;

形式:

cout << 10 + 2 * 2; // 14

但是預先評估的 constexpr 會正確地給出 24

const 的比較

const 變數是一個需要記憶體的變數。一個 constexpr 沒有。constexpr 產生編譯時常量,不能改變。你可能會說,const 也可能不會改變。但請考慮:

int main()
{
   const int size1 = 10;
   const int size2 = abs(10);

   int arr_one[size1]; 
   int arr_two[size2]; 
}

對於大多數編譯器,第二個語句將失敗(例如,可能與 GCC 一起使用)。你可能知道,任何陣列的大小都必須是常量表示式(即導致編譯時值)。第二個變數 size2 被分配了一些在執行時決定的值(即使你知道它是 10,對於編譯器來說它不是編譯時)。

這意味著 const 可能是也可能不是真正的編譯時常量。你不能保證或強制執行特定的 const 值絕對是編譯時。你可以使用 #define 但它有自己的陷阱。

因此,只需使用:

Version >= C++ 11

int main()
{
    constexpr int size = 10;

    int arr[size];
}

constexpr 表示式必須求值為編譯時值。因此,你不能使用:

Version >= C++ 11

constexpr int size = abs(10);

除非函式(abs)本身返回一個 constexpr

所有基本型別都可以使用 constexpr 進行初始化。

Version >= C++ 11

constexpr bool FailFatal = true;
constexpr float PI = 3.14f;
constexpr char* site= "StackOverflow";

有趣的是,你也可以方便地使用 auto

Version >= C++ 11

constexpr auto domain = ".COM";  // const char * const domain = ".COM"
constexpr auto PI = 3.14;        // constexpr double