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