名稱空間
變體
操作

函式契約說明符 (C++26 起)

來自 cppreference.com
< cpp‎ | language‎ | functions
 
 
C++ 語言
 
 

函式契約說明符(前置條件以 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) 後置條件

[編輯] 關鍵詞

pre, post

[編輯] 注意

功能測試宏 標準 特性
__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) 在執行期間驗證內部條件[編輯]