static_assert
declaration
(since C++11)
Выполняет проверку утверждений на этапе компиляции.
Содержание |
Синтаксис
static_assert(
bool-constexpr
,
unevaluated-string
)
|
(1) | ||||||||
static_assert(
bool-constexpr
)
|
(2) | (начиная с C++17) | |||||||
static_assert(
bool-constexpr
,
constant-expression
)
|
(3) | (начиная с C++26) | |||||||
Объявляет статическое утверждение. Если утверждение не выполняется, программа является некорректной, и может быть сгенерировано диагностическое сообщение об ошибке.
Объяснение
| bool-constexpr | - |
|
||||
| unevaluated-string | - | невычисляемый строковый литерал , который будет отображаться как сообщение об ошибке | ||||
| constant-expression | - |
константное выражение
msg
, удовлетворяющее всем следующим условиям:
|
Объявление static_assert может появляться в области видимости пространства имён и блока (scope) (как объявление блока ) и внутри тела класса (как объявление члена ).
Если bool-constexpr является корректно сформированным и вычисляется в true , или вычисляется в контексте определения шаблона и шаблон не инстанцирован, данное объявление не имеет эффекта. В противном случае возникает ошибка компиляции, и предоставленное пользователем сообщение (если есть) включается в диагностическое сообщение.
Текст предоставленного пользователем сообщения определяется следующим образом:
- Если сообщение соответствует синтаксическим требованиям unevaluated-string , текст сообщения является текстом unevaluated-string .
|
(since C++26) |
Примечания
Стандарт не требует от компилятора вывода дословного текста сообщения об ошибке , хотя компиляторы обычно делают это по возможности.
|
Поскольку сообщение об ошибке должно быть строковым литералом, оно не может содержать динамическую информацию или даже константное выражение , которое само не является строковым литералом. В частности, оно не может содержать имя аргумента шаблонного типа . |
(до C++26) |
| Макрос тестирования возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_static_assert
|
200410L
|
(C++11) | static_assert (синтаксис ( 1 ) ) |
201411L
|
(C++17) | Однопараметрический static_assert (синтаксис ( 2 ) ) | |
202306L
|
(C++26) | Пользовательские сообщения об ошибках (синтаксис ( 3 ) ) |
Ключевые слова
Пример
#include <format> #include <type_traits> static_assert(03301 == 1729); // начиная с C++17 строка сообщения является необязательной template<class T> void swap(T& a, T& b) noexcept { static_assert(std::is_copy_constructible_v<T>, "Swap requires copying"); static_assert(std::is_nothrow_copy_constructible_v<T> && std::is_nothrow_copy_assignable_v<T>, "Swap requires nothrow copy/assign"); auto c = b; b = a; a = c; } template<class T> struct data_structure { static_assert(std::is_default_constructible_v<T>, "Data structure requires default-constructible elements"); }; template<class> constexpr bool dependent_false = false; // обходное решение до CWG2518/P2593R1 template<class T> struct bad_type { static_assert(dependent_false<T>, "error on instantiation, workaround"); static_assert(false, "error on instantiation"); // OK благодаря CWG2518/P2593R1 }; struct no_copy { no_copy(const no_copy&) = delete; no_copy() = default; }; struct no_default { no_default() = delete; }; #if __cpp_static_assert >= 202306L // Еще не настоящий C++ (std::format должен быть constexpr для работы): static_assert(sizeof(int) == 4, std::format("Expected 4, got {}", sizeof(int))); #endif int main() { int a, b; swap(a, b); no_copy nc_a, nc_b; swap(nc_a, nc_b); // 1 [[maybe_unused]] data_structure<int> ds_ok; [[maybe_unused]] data_structure<no_default> ds_error; // 2 }
Возможный вывод:
1: error: static assertion failed: Swap requires copying 2: error: static assertion failed: Data structure requires default-constructible elements 3: error: static assertion failed: Expected 4, got 2
Отчёты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Применяется к | Поведение в опубликованной версии | Корректное поведение |
|---|---|---|---|
| CWG 2039 | C++11 | только выражение до преобразования должно быть константным |
преобразование также должно быть
допустимо в константном выражении |
|
CWG 2518
( P2593R1 ) |
C++11 | неинстанцированный static_assert ( false , "" ) ; был некорректным | сделан корректным |
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2024):
-
- 9.1 Преамбула [dcl.pre] (стр: 10)
- Стандарт C++20 (ISO/IEC 14882:2020):
-
- 9.1 Преамбула [dcl.pre] (стр: 6)
- Стандарт C++17 (ISO/IEC 14882:2017):
-
- 10 Объявления [dcl.dcl] (стр.: 6)
- Стандарт C++14 (ISO/IEC 14882:2014):
-
- 7 Объявления [dcl.dcl] (стр: 4)
- Стандарт C++11 (ISO/IEC 14882:2011):
-
- 7 Объявления [dcl.dcl] (стр: 4)
Смотрите также
|
выводит заданное сообщение об ошибке и делает программу некорректной
(директива препроцессора) |
|
|
аварийно завершает программу, если заданное пользователем условие не
true
. Может быть отключен для релизных сборок.
(функциональный макрос) |
|
contract_assert
statement
(C++26)
|
проверяет внутреннее условие во время выполнения |
|
(C++11)
|
условно
удаляет
перегрузку функции или специализацию шаблона из разрешения перегрузки
(шаблон класса) |
| Type traits (C++11) | определяют интерфейсы на основе шаблонов времени компиляции для запроса свойств типов |
|
Документация C
для
Статическое утверждение
|
|