Function contract specifiers (since C++26)
Спецификаторы контракта функции (предусловия, обозначаемые с помощью pre и постусловия, обозначаемые с помощью post ) — это спецификаторы, которые могут применяться к декларатору функции или лямбда-выражения для введения утверждения контракта функции соответствующего типа в связанную функцию.
Они гарантируют, что указанное условие выполняется во время исполнения, вызывая нарушение (например, завершение программы) в отладочных сборках, если условие вычисляется в false или вычисление завершается через исключение, и могут игнорироваться в релизных сборках для повышения производительности.
Содержание |
Предусловие
Условие ( pre ) — это предикат, который вызывающая сторона должна гарантировать выполнение до вызова функции или лямбды, проверяемый в отладочных сборках для валидации входных данных или состояния.
Постусловие
Постусловие ( post ) — это предикат, который вызываемый объект должен гарантировать выполнение после завершения функции или лямбды, проверяемый в отладочных сборках для подтверждения вывода или состояния.
Синтаксис
pre
attr
(необязательно)
(
expr
)
|
(1) | ||||||||
post
attr
(необязательно)
(
result-name
(необязательно)
predicate
)
|
(2) | ||||||||
| attr | - | любое количество атрибутов |
| result-name | - |
identifier
:
|
| identifier | - | имя привязки результата ассоциированной функции |
| predicate | - | логическое выражение, которое должно вычисляться в true |
Ключевые слова
Примечания
| Макрос проверки функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__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
statement
(C++26)
|
проверяет внутреннее условие во время выполнения |