Function contract specifiers (since C++26)
関数契約指定子( pre で記述される事前条件と post で記述される事後条件)は、関数またはラムダ式の宣言子に適用可能な指定子であり、対応する関数にそれぞれの種類の関数契約表明を導入するものです。
これらは実行中に指定された条件が保持されることを保証し、条件が false と評価された場合、または評価が例外によって終了した場合に、デバッグビルドでは違反(例:終了)を引き起こし、パフォーマンス向上のためリリースビルドでは無視されることがあります。
目次 |
事前条件
事前条件 ( pre ) は、 呼び出し元 が関数またはラムダの呼び出し 前 に満たされていることを保証しなければならない述語であり、デバッグビルドで入力や状態を検証するためにチェックされます。
事後条件
事後条件( post )は、 callee が関数またはラムダの完了 後 に保持されることを保証しなければならない述語であり、出力または状態を確認するためにデバッグビルドで検証されます。
構文
pre
attr
(オプション)
(
expr
)
|
(1) | ||||||||
post
attr
(オプション)
(
result-name
(オプション)
predicate
)
|
(2) | ||||||||
| attr | - | 任意の数の 属性 |
| result-name | - |
identifier
:
|
| identifier | - | 関連する関数の結果バインディングの名前 |
| predicate | - | true に評価されるべきブール式 |
キーワード
注記
| 機能テストマクロ | 値 | 規格 | 機能 |
|---|---|---|---|
__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}); // 事前条件と事後条件に違反 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)
|
実行中の内部条件を検証する |