static_assert объявление (начиная с 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 может находиться в пространстве имён и в блочной области видимости (как объявление блока), а также внутри тела класса (как объявление-член).
Если bool-constexpr корректно и вычисляется в значение true либо вычисляется в контексте определения шаблона, а сам шаблон не инстанцирован, это объявление не оказывает никакого эффекта. В противном случае возникает ошибка компиляции, а предоставленное пользователем сообщение, если оно есть, включается в диагностическое сообщение.
Текст сообщения, предоставленного пользователем, определяется следующим образом:
- Если сообщение соответствует синтаксическим требованиям к unevaluated-string, текстом сообщения является текст unevaluated-string.
| (начиная с 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); // since C++17 the message string is optional
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; // workaround before CWG2518/P2593R1
template<class T>
struct bad_type
{
static_assert(dependent_false<T>, "error on instantiation, workaround");
static_assert(false, "error on instantiation"); // OK because of 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
// Not real C++ yet (std::format should be constexpr to work):
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 (C++26) | проверяет внутреннее условие во время выполнения |
|
(C++11) | условно исключает перегрузку функции или специализацию шаблона из разрешения перегрузки (шаблон класса) |
| Характеристики типов (C++11) | определяют интерфейсы на основе шаблонов для запроса свойств типов во время компиляции |
| Документация по C для статического утверждения | |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/static_assert