命名空间
变体
操作

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

来自 cppreference.cn
< cpp‎ | language‎ | functions
 
 
C++ 语言
 
 

函数契约说明符(前置条件以 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) 后置条件

[编辑] 关键词

pre, post

[编辑] 注意

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