Объявление static_assert
(начиная с C++11)
Выполняет проверку утверждений во время компиляции.
Содержание |
[править]Синтаксис
static_assert( логическое-constexpr, сообщение) | (начиная с C++11) | ||||||||
static_assert( логическое-constexpr) | (начиная с C++17) | ||||||||
[править]Объяснение
логическое-constexpr | — |
| ||||
сообщение | — |
|
Объявление static_assert может появляться в пространстве имён и области видимости блока (как объявление блока) и внутри тела класса (как объявление элемента).
Если логическое-constexpr возвращает true, это объявление не действует. В противном случае выдаётся ошибка времени компиляции, и текст сообщения, если таковой имеется, включается в диагностическое сообщение.
Если сообщение не является строковым литералом, оно оценивается только в том случае, если логическое-constexpr оценивается как false. Текст сообщения формируется последовательностью символов | (начиная с 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) | условно удаляет перегрузку функции или специализацию шаблона из разрешения перегрузки (шаблон класса) |
Свойства типа(C++11) | определяет интерфейс на основе шаблона времени компиляции для запроса или изменения свойств типов |
Документация C по Статическое утверждение |