函数契约说明符 (C++26 起)

来自cppreference.com
< cpp‎ | language‎ | functions


 
 
C++ 语言
 
 

函数契约说明符(前条件写为 pre,后条件写为 post)是可应用于函数或 lambda 表达式的声明符的说明符,以向对应函数引入相应种类的函数契约断言。

它们确保指定的条件成立在执行时,在调试构建中当条件求值为 false,或者求值由于异常退出时触发违例(如终止程序),也可在发布构建中为性能而将之忽略。

目录

[编辑] 前条件

前条件 (pre) 是调用方必须确保于调用函数或 lambda 之前 成立的谓词,调试构建中检查它以验证输入或状态。

[编辑] 后条件

后条件 (post) 是被调用方必须确保于函数或 lambda 执行结束之后 成立的谓词,调试构建中验证它以确认输出或状态。

[编辑] 语法

pre 属性 (可选) ( 表达式 ) (1)
post 属性 (可选) ( 结果名 (可选) 谓词 ) (2)
属性 - 任意数量的属性
结果名 - 标识符 :
标识符 - 与关联函数的结果绑定的名字
谓词 - 应当求值为 true 的布尔表达式
1) 前条件
2) 后条件

[编辑] 关键词

pre, post

[编辑] 注解

功能特性测试宏 标准 功能特性
__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) 在执行中验证一项内部条件[编辑]