Объявление static_assert (начиная с C++11) — cppreference.com
Материал из cppreference.com
Выполняет проверку утверждений во время компиляции.
Синтаксис
static_assert( логическое-constexpr , сообщение )
|
(начиная с C++11) | ||||||||
static_assert( логическое-constexpr )
|
(начиная с C++17) | ||||||||
Объяснение
| логическое-constexpr | — | |||
| сообщение | — |
|
Объявление static_assert может появляться в пространстве имён и области видимости блока (как объявление блока) и внутри тела класса (как объявление элемента).
Если логическое-constexpr возвращает true, это объявление не действует. В противном случае выдаётся ошибка времени компиляции, и текст сообщения, если таковой имеется, включается в диагностическое сообщение.
|
Если сообщение не является строковым литералом, оно оценивается только в том случае, если логическое-constexpr оценивается как |
(начиная с C++26) |
Примечание
Стандарт не требует, чтобы компилятор печатал дословный текст сообщения, хотя компиляторы обычно делают это, насколько возможно.
|
Поскольку сообщение должно быть строковым литералом, оно не может содержать динамическую информацию или даже константное выражение, которое не является строковым литералом. В частности, оно не может содержать имя аргумента типа шаблона. |
(до C++26) |
| Макрос тест функциональности | Значение | Стандарт | Комментарий |
|---|---|---|---|
__cpp_static_assert |
200410L |
(C++11) | static_assert(логическое значение constexpr ,"комментарий")
|
201411L |
(C++17) | Один аргумент static_assert(логическое значение constexpr )
| |
202306L |
(C++26) | генерируемые пользователем сообщения static_assert
|
Примеры
#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>, "Обмен требует копирования"); static_assert(std::is_nothrow_copy_constructible_v<T> && std::is_nothrow_copy_assignable_v<T>, "Обмен требует небросающее исключение\n копирование/присваивание"); auto c = b; b = a; a = c; } template <class T> struct data_structure { static_assert(std::is_default_constructible_v<T>, "Для структуры данных требуются элементы,\n конструируемые по умолчанию"); }; 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("Ожидается 4, получается {}", 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: Обмен требует копирования 2: error: static assertion failed: Для структуры данных требуются элементы, конструируемые по умолчанию 3: error: static assertion failed: Ожидается 4, получается 2
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| CWG 2039 | C++11 | выражение должно быть константным только перед преобразованием | преобразование также должно быть действительным в константном выражении |
Смотрите также
| показывает данное сообщение об ошибке и делает программу ошибочной (директива предварительной обработки) [править] | |
прерывает выполнение программы, если указанное пользователем условие не равно true. Может быть отключено для релизовых сборок (функция-макрос) [править] | |
| условно удаляет перегрузку функции или специализацию шаблона из разрешения перегрузки (шаблон класса) [править] | |
| Свойства типа (C++11) | определяет интерфейс на основе шаблона времени компиляции для запроса или изменения свойств типов |