Namespaces
Variants

Function contract specifiers (since C++26)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

함수 계약 지정자( pre 로 명시된 사전조건과 post 로 명시된 사후조건)는 해당 함수에 해당 종류의 함수 계약 어설션을 도입하기 위해 함수 또는 람다 표현식의 선언자에 적용될 수 있는 지정자입니다.

지정된 조건이 실행 중에 유지되도록 보장하며, 조건이 false 로 평가되거나 예외를 통해 평가가 종료되는 경우 디버그 빌드에서 위반(예: 종료)을 트리거하고, 성능을 위해 릴리스 빌드에서는 무시될 수 있습니다.

목차

사전 조건

사전 조건( pre )은 호출자가 함수나 람다를 호출하기 전에 반드시 충족되어야 하는 조건자로, 디버그 빌드에서 입력값이나 상태를 검증하기 위해 확인됩니다.

사후 조건

사후 조건( post )은 함수나 람다가 완료된 피호출자 가 반드시 충족시켜야 하는 조건자로, 디버그 빌드에서 출력이나 상태를 확인하기 위해 검증됩니다.

구문

pre attr  (선택 사항) ( expr ) (1)
post attr  (선택 사항) ( result-name  (선택 사항) predicate ) (2)
attr - 임의의 수의 attributes
result-name - identifier :
identifier - 관련 함수의 결과 바인딩 이름
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}); // 선조건과 후조건을 위반함
    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) 실행 중 내부 조건을 검증함