Namespaces
Variants

Function contract specifiers (since C++26)

From es.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

Los especificadores de contrato de función (precondiciones escritas con pre y postcondiciones escritas con post ) son especificadores que pueden aplicarse al declarador de una función o de una expresión lambda para introducir una aserción de contrato de función del tipo correspondiente a la función respectiva.

Garantizan que la condición especificada se mantenga durante la ejecución, activando una violación (por ejemplo, terminación) en compilaciones de depuración si la condición se evalúa como false o la evaluación finaliza mediante una excepción, y pueden ignorarse en compilaciones de lanzamiento por rendimiento.

Contenidos

Precondición

Una precondición ( pre ) es un predicado que el llamador debe garantizar que se cumple antes de invocar una función o lambda, verificada en compilaciones de depuración para validar entradas o estado.

Postcondición

Una postcondición ( post ) es un predicado que el callee debe garantizar que se cumple después de que una función o lambda finalice, verificado en builds de depuración para confirmar la salida o el estado.

Sintaxis

pre attr  (opcional) ( expr ) (1)
post attr  (opcional) ( result-name  (opcional) predicate ) (2)
attr - cualquier número de atributos
result-name - identifier :
identifier - nombre de un enlace de resultado de la función asociada
predicate - expresión booleana que debe evaluarse como true
1) Precondición
2) Postcondición

Palabras clave

pre , post

Notas

Macro de prueba de características Valor Std Característica
__cpp_contracts 202502L (C++26) Contratos

Ejemplo

  • La precondición de la función normalize requiere que el llamador pase un vector normalizable.
  • La postcondición asegura que la función normalize retorna un vector normalizado.
#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}); // viola las condiciones pre y post
    std::println("{}", w);
}

Salida posible:

[0.4242641, 0.56568545, 0.70710677]
[-nan, -nan, -nan]

Referencias

  • Estándar C++26 (ISO/IEC 14882:2026):
  • 9.(3+ c  ) Especificadores de contrato de función [dcl.contract]

Véase también

Aserciones de contrato (C++26) especifica propiedades que deben cumplirse en ciertos puntos durante la ejecución
contract_assert statement (C++26) verifica una condición interna durante la ejecución