函数契约说明符 (C++26 起)
来自 cppreference.cn
函数契约说明符 (前置条件用 pre 拼写,后置条件用 post 拼写) 是可以应用于函数或 lambda 表达式声明符的说明符,用于向相应的函数引入相应类型的函数契约断言。
它们确保在执行期间指定的条件成立,如果条件评估为 false 或评估通过异常退出,则在调试版本中触发违规 (例如终止),并且为了性能可以在发布版本中忽略。
目录 |
[编辑] 前置条件
前置条件 (pre) 是调用者必须确保在调用函数或 lambda 之前成立的谓词,在调试版本中检查以验证输入或状态。
[编辑] 后置条件
后置条件 (post) 是被调用者必须确保在函数或 lambda 完成后成立的谓词,在调试版本中验证以确认输出或状态。
[编辑] 语法
pre attr(可选) ( expr ) |
(1) | ||||||||
post attr(可选) ( result-name(可选) predicate ) |
(2) | ||||||||
attr | - | 任意数量的 属性 |
result-name | - | identifier : |
identifier | - | 关联函数的结果绑定的名称 |
predicate | - | 应该评估为 true 的布尔表达式 |
1) 前置条件
2) 后置条件
[编辑] 关键字
[编辑] 注释
特性测试宏 | 值 | Std | 特性 |
---|---|---|---|
__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) |
验证执行期间的内部条件 |