Spec-Zone.ru › C++

static_assert объявление (с C++11)

Выполняет проверку утверждения на этапе компиляции.

Синтаксис

static_assert( bool-constexpr , сообщение ) (с C++11)
static_assert( bool-constexpr ) (с C++17)

Объяснение

bool-constexpr -

контекстно преобразованное константное выражение типа bool. Встроенные преобразования запрещены, за исключением не-сужающих целочисленных преобразований к bool.

(до C++23)

выражение, контекстно преобразуемое к bool, где преобразование является константным выражением.

(с C++23)
сообщение -
  • невычисляемая строковая константа, которая будет отображаться как ошибка компилятора, если bool-constexpr ложно
  • или выражение msg, при условии, что
    • msg.size() неявно преобразуется к std::size_t
    • msg.data() неявно преобразуется к const char*
(с C++26)

Объявление static_assert может появляться в области видимости пространства имен и блока (как объявление блока) и внутри тела класса (как объявление члена).

Если bool-constexpr является корректным и вычисляется в true, или вычисляется в контексте определения шаблона, и шаблон не инстанцирован, это объявление не имеет эффекта. В противном случае выдаётся ошибка компиляции, и текст сообщения, если он есть, включается в диагностическое сообщение.

Если сообщение не является строковой константой, оно оценивается только в том случае, если bool-constexpr вычисляется в false. Текст сообщения формируется из последовательности символов [msg.data(), msg.data() + msg.size()), которая должна определять допустимый диапазон, а каждый элемент последовательности должен быть целочисленным константным выражением.

(с C++26)

Примечания

Стандарт не требует от компилятора печатать текст сообщения дословно, хотя компиляторы обычно делают это по возможности.

Поскольку сообщение должно быть строковой константой, оно не может содержать динамической информации или даже константного выражения, которое само по себе не является строковой константой. В частности, оно не может содержать имя имени аргумента типа шаблона.

(до C++26)
Макрос проверки возможностей Значение Стандарт Функция
__cpp_static_assert 200410L (C++11) static_assert(bool-constexpr , "comment")
201411L (C++17) Одноаргументное static_assert(bool-constexpr )
202306L (C++26) сообщения, сгенерированные пользователем static_assert

Пример

#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++.

Отчёт Применён к Поведение по публикации Правильное поведение
CWG 2039 C++11 требовалось, чтобы только выражение перед преобразованием было константным преобразование также должно быть
корректным в константном выражении
CWG 2518 C++11 неинстанцированное static_assert(false, ""); вызывало ошибку сделано корректным

См. также

#error
отображает указанное сообщение об ошибке и делает программу некорректной
(препроцессорная директива)
assert
прерывает программу, если указанное пользователем условие не true. Может быть отключено для релизных сборок
(функциональная макрос)
enable_if
(C++11)
условно удаляет перегрузку функции или специализацию шаблона из разрешения перегрузки
(шаблон класса)
Типы-свойства (C++11) определяет интерфейс шаблонов на этапе компиляции для запроса или изменения свойств типов
Документация C по Статическому утверждению

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/static_assert

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API