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

Funktionsvertragsspezifizierer (Vorbedingungen gekennzeichnet mit pre und Nachbedingungen gekennzeichnet mit post ) sind Spezifizierer, die auf den Deklarator einer Funktion oder eines Lambda-Ausdrucks angewendet werden können, um eine Funktionsvertragsassertion der jeweiligen Art in die entsprechende Funktion einzuführen.

Sie stellen sicher, dass die angegebene Bedingung während der Ausführung erfüllt ist, und lösen eine Verletzung (z.B. Abbruch) in Debug-Builds aus, falls die Bedingung zu false ausgewertet wird oder die Auswertung über eine Exception beendet wird, und können in Release-Builds aus Performance-Gründen ignoriert werden.

Inhaltsverzeichnis

Vorbedingung

Eine Vorbedingung ( pre ) ist ein Prädikat, das der Aufrufer sicherstellen muss, bevor er eine Funktion oder Lambda aufruft, geprüft in Debug-Builds zur Validierung von Eingaben oder Zuständen.

Postbedingung

Eine Nachbedingung ( post ) ist ein Prädikat, das der Aufgerufene sicherstellen muss, das nach dem Abschluss einer Funktion oder eines Lambdas gilt, überprüft in Debug-Builds zur Bestätigung der Ausgabe oder des Zustands.

Syntax

pre attr  (optional) ( expr ) (1)
post attr  (optional) ( result-name  (optional) predicate ) (2)
attr - beliebige Anzahl von attributes
result-name - identifier :
identifier - Name einer Ergebnisbindung der zugehörigen Funktion
predicate - boolescher Ausdruck, der zu true ausgewertet werden sollte
1) Vorbedingung
2) Nachbedingung

Schlüsselwörter

pre , post

Hinweise

Feature-Test-Makro Wert Std Feature
__cpp_contracts 202502L (C++26) Contracts

Beispiel

  • Die Vorbedingung der Funktion normalize erfordert, dass der Aufrufer einen normalisierbaren Vektor übergibt.
  • Die Nachbedingung stellt sicher, dass die Funktion normalize einen normalisierten Vektor zurückgibt.
#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}); // verletzt Vorbedingungen und Nachbedingungen
    std::println("{}", w);
}

Mögliche Ausgabe:

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

Referenzen

  • C++26 Standard (ISO/IEC 14882:2026):
  • 9.(3+ c  ) Funktionsvertragsspezifizierer [dcl.contract]

Siehe auch

Contract assertions (C++26) spezifiziert Eigenschaften, die an bestimmten Punkten während der Ausführung gelten müssen
contract_assert statement (C++26) überprüft eine interne Bedingung während der Ausführung