関数契約指定子 (C++26以降)
From cppreference.com
関数契約指定子(pre で記述される事前条件と post で記述される事後条件)は、関数またはラムダ式の宣言子に適用して、それぞれの種類の関数契約アサーションを導入できる指定子です。
これらは、実行中に指定された条件が成り立つことを保証し、デバッグビルドで条件が false と評価された場合や、例外を介して評価が終了した場合に違反(例: 終了)をトリガーし、リリースビルドではパフォーマンスのために無視できます。
目次 |
[編集] 事前条件
事前条件(pre)は、関数またはラムダを呼び出す *前に* 呼び出し元が満たす必要がある述語であり、デバッグビルドで入力を検証したり状態を確認したりするためにチェックされます。
[編集] 事後条件
事後条件(post)は、関数またはラムダが完了した *後に* 被呼び出し元が満たす必要がある述語であり、デバッグビルドで出力を確認したり状態を検証したりするために使われます。
[編集] 構文
pre attr (optional) ( expr ) |
(1) | ||||||||
post attr (optional) ( result-name (optional) predicate ) |
(2) | ||||||||
| attr | - | 任意の数の属性 |
| result-name | - | identifier : |
| identifier | - | 関連する関数の結果バインディングの名前 |
| 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) |
実行中に内部条件を検証する |