std::is_constant_evaluated
來自 cppreference.com
定義於標頭檔案 <type_traits> |
||
constexpr bool is_constant_evaluated() noexcept; |
(C++20 起) | |
檢測函式呼叫是否發生在常量求值上下文中。如果呼叫的求值發生在顯式常量求值的表示式或轉換的求值中,則返回true;否則返回false。
為了確定以下變數的初始化器是否為顯式常量求值,編譯器可能會首先執行試探性常量求值:
- 引用型別或 const 限定的整型或列舉型別的變數;
- 靜態和執行緒區域性變數。
不建議在這種情況下依賴結果。
int y = 0; const int a = std::is_constant_evaluated() ? y : 1; // Trial constant evaluation fails. The constant evaluation is discarded. // Variable a is dynamically initialized with 1 const int b = std::is_constant_evaluated() ? 2 : y; // Constant evaluation with std::is_constant_evaluated() == true succeeds. // Variable b is statically initialized with 2
目錄 |
[編輯] 引數
(無)
[編輯] 返回值
如果呼叫的求值發生在顯式常量求值的表示式或轉換的求值中,則返回true;否則返回false。
[編輯] 可能的實現
// This implementation requires C++23 if consteval. constexpr bool is_constant_evaluated() noexcept { if consteval { return true; } else { return false; } } |
[編輯] 注意
當直接用作static_assert宣告或constexpr if 語句的條件時,std::is_constant_evaluated()始終返回true。
由於C++20中沒有if consteval,std::is_constant_evaluated
通常使用編譯器擴充套件來實現。
特性測試宏 | 值 | 標準 | 特性 |
---|---|---|---|
__cpp_lib_is_constant_evaluated |
201811L |
(C++20) | std::is_constant_evaluated
|
[編輯] 示例
執行此程式碼
#include <cmath> #include <iostream> #include <type_traits> constexpr double power(double b, int x) { if (std::is_constant_evaluated() && !(b == 0.0 && x < 0)) { // A constant-evaluation context: Use a constexpr-friendly algorithm. if (x == 0) return 1.0; double r {1.0}; double p {x > 0 ? b : 1.0 / b}; for (auto u = unsigned(x > 0 ? x : -x); u != 0; u /= 2) { if (u & 1) r *= p; p *= p; } return r; } else { // Let the code generator figure it out. return std::pow(b, double(x)); } } int main() { // A constant-expression context constexpr double kilo = power(10.0, 3); int n = 3; // Not a constant expression, because n cannot be converted to an rvalue // in a constant-expression context // Equivalent to std::pow(10.0, double(n)) double mucho = power(10.0, n); std::cout << kilo << " " << mucho << "\n"; // (3) }
輸出
1000 1000
[編輯] 參閱
constexpr 說明符(C++11) |
指定變數或函式的值可在編譯時計算 |
consteval 說明符(C++20) |
指定函式是一個“即時函式”(immediate function),即每次對函式的呼叫都必須在常量求值中進行 |
constinit 說明符(C++20) |
斷言變數具有靜態初始化,即零初始化和常量初始化 |