Namespaces
Variants

static_assert declaration (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Realiza comprobación de aserciones en tiempo de compilación.

Contenidos

Sintaxis

static_assert( bool-constexpr , unevaluated-string ) (1)
static_assert( bool-constexpr ) (2) (desde C++17)
static_assert( bool-constexpr , constant-expression ) (3) (desde C++26)

Declara una aserción estática. Si la aserción falla, el programa está mal formado y puede generarse un mensaje de error de diagnóstico.

1) Una aserción estática con mensaje de error fijo.
2) Una aserción estática sin mensaje de error.
3) Una aserción estática con mensaje de error generado por el usuario.
Esta sintaxis solo puede coincidir si la sintaxis ( 1 ) no coincide.

Explicación

bool-constexpr -

una expresión constante convertida contextualmente de tipo bool . No se permiten conversiones incorporadas, excepto para conversiones integrales no restrictivas a bool .

(hasta C++23)

una expresión convertida contextualmente a bool donde la conversión es una expresión constante

(desde C++23)
unevaluated-string - un literal de cadena no evaluado que aparecerá como el mensaje de error
constant-expression - una expresión constante msg que satisface todas las siguientes condiciones:
  • msg. size ( ) es convertible implícitamente a std::size_t .
  • msg. data ( ) es convertible implícitamente a const char * .

Una declaración static_assert puede aparecer en el ámbito de espacio de nombres y de bloque scope (como una declaración de bloque ) y dentro del cuerpo de una clase (como una declaración de miembro ).

Si bool-constexpr está bien formado y evalúa a true , o es evaluado en el contexto de una definición de plantilla y la plantilla no está instanciada, esta declaración no tiene efecto. De lo contrario, se emite un error en tiempo de compilación, y el mensaje proporcionado por el usuario, si existe, se incluye en el mensaje de diagnóstico.

El texto del mensaje proporcionado por el usuario se determina de la siguiente manera:

  • Si el mensaje coincide con los requisitos sintácticos de unevaluated-string , el texto del mensaje es el texto de la unevaluated-string .
  • En caso contrario, dadas las siguientes valores:
El texto del mensaje está formado por la secuencia de len unidades de código , comenzando en ptr , de la codificación literal ordinaria . Para cada entero i en [ 0 , len ) , ptr [ i ] debe ser una expresión constante integral .
(desde C++26)

Notas

El estándar no requiere que un compilador imprima el texto literal del mensaje de error , aunque los compiladores generalmente lo hacen tanto como es posible.

Dado que el mensaje de error debe ser un literal de cadena, no puede contener información dinámica o incluso una expresión constante que no sea un literal de cadena en sí mismo. En particular, no puede contener el nombre del argumento de tipo de plantilla .

(until C++26)
Macro de prueba de características Valor Std Característica
__cpp_static_assert 200410L (C++11) static_assert (sintaxis ( 1 ) )
201411L (C++17) static_assert de un solo argumento (sintaxis ( 2 ) )
202306L (C++26) Mensajes de error generados por el usuario (sintaxis ( 3 ) )

Palabras clave

static_assert

Ejemplo

#include <format>
#include <type_traits>
static_assert(03301 == 1729); // desde C++17 el mensaje de texto es opcional
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; // solución temporal antes de CWG2518/P2593R1
template<class T>
struct bad_type
{
    static_assert(dependent_false<T>, "error on instantiation, workaround");
    static_assert(false, "error on instantiation"); // OK debido a 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
// No es C++ real aún (std::format debería ser constexpr para funcionar):
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
}

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Se aplica a Comportamiento publicado Comportamiento correcto
CWG 2039 C++11 solo la expresión antes de la conversión debe ser constante la conversión también debe ser
válida en una expresión constante
CWG 2518
( P2593R1 )
C++11 static_assert ( false , "" ) ; sin instanciar era incorrecto se hizo correcto

Referencias

  • Estándar C++23 (ISO/IEC 14882:2024):
  • 9.1 Preámbulo [dcl.pre] (p: 10)
  • Estándar C++20 (ISO/IEC 14882:2020):
  • 9.1 Preámbulo [dcl.pre] (p: 6)
  • Estándar C++17 (ISO/IEC 14882:2017):
  • 10 Declaraciones [dcl.dcl] (p: 6)
  • Estándar C++14 (ISO/IEC 14882:2014):
  • 7 Declaraciones [dcl.dcl] (p: 4)
  • Estándar C++11 (ISO/IEC 14882:2011):
  • 7 Declaraciones [dcl.dcl] (p: 4)

Véase también

muestra el mensaje de error dado y hace que el programa sea incorrecto
(directiva de preprocesador)
aborta el programa si la condición especificada por el usuario no es true . Puede deshabilitarse para builds de release.
(macro de función)
contract_assert statement (C++26) verifica una condición interna durante la ejecución
(C++11)
condicionalmente elimina una sobrecarga de función o especialización de plantilla de la resolución de sobrecarga
(plantilla de clase)
Type traits (C++11) define interfaces basadas en plantillas en tiempo de compilación para consultar las propiedades de los tipos
Documentación de C para Static assertion