函数契约说明符 (C++26 起)
来自cppreference.com
函数契约说明符(前条件写为 pre,后条件写为 post)是可应用于函数或 lambda 表达式的声明符的说明符,以向对应函数引入相应种类的函数契约断言。
它们确保指定的条件成立在执行时,在调试构建中当条件求值为 false,或者求值由于异常退出时触发违例(如终止程序),也可在发布构建中为性能而将之忽略。
目录 |
[编辑] 前条件
前条件 (pre) 是调用方必须确保于调用函数或 lambda 之前 成立的谓词,调试构建中检查它以验证输入或状态。
[编辑] 后条件
后条件 (post) 是被调用方必须确保于函数或 lambda 执行结束之后 成立的谓词,调试构建中验证它以确认输出或状态。
[编辑] 语法
pre 属性 (可选) ( 表达式 )
|
(1) | ||||||||
post 属性 (可选) ( 结果名 (可选) 谓词 )
|
(2) | ||||||||
属性 | - | 任意数量的属性 |
结果名 | - | 标识符 :
|
标识符 | - | 与关联函数的结果绑定的名字 |
谓词 | - | 应当求值为 true 的布尔表达式 |
1) 前条件
2) 后条件
[编辑] 关键词
[编辑] 注解
功能特性测试宏 | 值 | 标准 | 功能特性 |
---|---|---|---|
__cpp_contracts |
202502L |
(C++26) | 契约 |
[编辑] 示例
- 函数
normalize
的前条件要求调用方传递可正规化的向量。 - 后条件则保证函数
normalize
返回正规化后的vector
。
运行此代码
#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 ) Function contract specifiers [dcl.contract]
[编辑] 参阅
契约断言 (C++26) | 指定必须于执行过程中特定位置成立的性质 |
contract_assert 语句 (C++26)
|
在执行中验证一项内部条件 |