static_assert
declaration
(since C++11)
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.
Explicación
| bool-constexpr | - |
|
||||
| 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:
|
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 .
|
(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
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
|
|