函数契约说明符 (C++26 起)
来自 cppreference.cn
函数契约说明符(前置条件以 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) |
在执行期间验证内部条件 |