Объявление static_assert (начиная с C++11)
Выполняет проверку утверждений во время компиляции.
Синтаксис
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) |
условно удаляет перегрузку функции или специализацию шаблона из разрешения перегрузки (шаблон класса) |
| Свойства типа (C++11) | определяет интерфейс на основе шаблона времени компиляции для запроса или изменения свойств типов |
Документация C по Статическое утверждение
| |