函式契約說明符 (C++26 起)
來自 cppreference.com
函式契約說明符(前置條件以 pre 表示,後置條件以 post 表示)是可以應用於函式或 lambda 表示式的宣告符的說明符,用於向相應的函式引入相應型別的函式契約斷言。
它們確保指定的條件在執行期間成立,如果在除錯構建中條件評估為 false 或評估透過異常退出,則會觸發違規(例如終止),在釋出構建中可以為了效能而忽略。
目錄 |
[編輯] 前置條件
前置條件 (pre) 是一個謂詞,呼叫方必須確保在呼叫函式或 lambda 之前成立,在除錯構建中檢查以驗證輸入或狀態。
[編輯] 後置條件
後置條件 (post) 是一個謂詞,被呼叫方必須確保在函式或 lambda 完成之後成立,在除錯構建中驗證以確認輸出或狀態。
[編輯] 語法
pre attr (可選) ( expr ) |
(1) | ||||||||
post attr (可選) ( result-name (可選) predicate ) |
(2) | ||||||||
屬性 | - | 任意數量的屬性 |
result-name | - | 識別符號 : |
識別符號 | - | 關聯函式的result繫結名稱 |
predicate | - | 應評估為 true 的布林表示式 |
1) 前置條件
2) 後置條件
[編輯] 關鍵詞
[編輯] 注意
功能測試宏 | 值 | 標準 | 特性 |
---|---|---|---|
__cpp_contracts |
202502L |
(C++26) | 契約 |
[編輯] 示例
- 函式
normalize
的前置條件要求呼叫方傳入可歸一化的向量。 - 後置條件確保函式
normalize
返回歸一化的向量。
執行此程式碼
#include <array> #include <cmath> #include <concepts> #include <contracts> #include <limits> #include <print> template <std::floating_point T> constexpr auto is_normalizable(const std::array<T, 3>& vector) noexcept { const auto& [x, y, z]{vector}; const auto norm{std::hypot(x, y, z)}; return std::isfinite(norm) && norm > T {0}; } template <std::floating_point T> constexpr auto is_normalized(const std::array<T, 3>& vector) noexcept { const auto& [x, y, z]{vector}; const auto norm{std::hypot(x, y, z)}; constexpr auto tolerance{010 * std::numeric_limits<T>::epsilon()}; if (!is_normalizable(norm)) [[unlikely]] return false; return std::abs(norm - T{1}) <= tolerance; } template <std::floating_point T> constexpr auto normalize(std::array<T, 3> vector) noexcept -> std::array<T, 3> pre(is_normalizable(vector)) post(vector: is_normalized(vector)) { auto& [x, y, z]{vector}; const auto norm{std::hypot(x, y, z)}; x /= norm, y /= norm, z /= norm; return vector; } int main() { const auto v = normalize<float>({0.3, 0.4, 0.5}); std::println("{}", v); const auto w = normalize<float>({0, 0, 0}); // violates pre- and post- conditions std::println("{}", w); }
可能的輸出
[0.4242641, 0.56568545, 0.70710677] [-nan, -nan, -nan]
[編輯] 參考
- C++26 標準 (ISO/IEC 14882:2026)
- 9.(3+c ) 函式契約說明符 [dcl.contract]
[編輯] 參閱
契約斷言 (C++26) | 指定在執行過程中某些點必須滿足的屬性 |
contract_assert 語句 (C++26) |
在執行期間驗證內部條件 |