Declaración static_assert
Lleva a cabo una comprobación de aserción en tiempo de compilación.
Sintaxis
static_assert( bool-constexpr , cadena-no-evaluada )
|
(1) | ||||||||
static_assert( bool-constexpr )
|
(2) | (desde C++17) | |||||||
static_assert( bool-constexpr , expresión-constante )
|
(3) | (desde C++26) | |||||||
Declara una aserción estática. Si la aserción falla, el programa queda mal formado y puede generarse un mensaje de error de diagnóstico.
Explicación
| bool-constexpr | - |
| ||||
| cadena-no-evaluada | - | una literal de cadena no evaluada que aparecerá como el mensaje de error. | ||||
| expresión-constante | - | una expresión constante msg que satisface todas las condiciones siguientes:
|
Una declaración static_assert puede aparecer en el espacio de nombres y bloque ámbito (como una declaración de bloque) y dentro del cuerpo de una clase (como una declaración de miembro).
Si bool-constexpr está bien formada y se evalúa como true, o se evalúa 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 de tiempo de compilación y el mensaje proporcionado por el usuario, si lo hay, 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 cadena-no-evaluada, el texto del mensaje es el texto de cadena-no-evaluada.
|
(desde C++26) |
Nota
El estándar no requiere que un compilador imprima el texto literal de message, aunque los compiladores generalmente lo hacen en la medida de lo posible.
|
Dado que message tiene que 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 plantilla de tipo. |
(hasta C++26) |
| Prueba de característica | Valor | Estándar | Comentario |
|---|---|---|---|
__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 la cadena de mensaje es opcional
template<class T>
void swap(T& a, T& b) noexcept
{
static_assert(std::is_copy_constructible_v<T>,
"El intercambio requiere copia");
static_assert(std::is_nothrow_copy_constructible_v<T> &&
std::is_nothrow_copy_assignable_v<T>,
"El intercambio requiere copia/asignación nothrow");
auto c = b;
b = a;
a = c;
}
template<class T>
struct data_structure
{
static_assert(std::is_default_constructible_v<T>,
"La estructura de datos requiere elementos construibles por defecto");
};
template<class>
constexpr bool dependent_false = false; // Solución alternativa antes de CWG2518/P2593R1
template<class T>
struct bad_type
{
static_assert(dependent_false<T>, "Error en la instanciación, solución alternativa");
static_assert(false, "Error en la instanciación"); // Está bien 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
// Aún no es C++ real (std::format debe ser constexpr para funcionar):
static_assert(sizeof(int) == 4, std::format("Se esperaba 4, se obtuvo {}", 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
}
Posible salida:
1: ERROR: la aserción estática falló: El intercambio requiere copia
2: ERROR: la aserción estática falló: La estructura de datos requiere elementos construibles por defecto
3: ERROR: la aserción estática falló: Se esperaba 4, se obtuvo 2
Informes de defectos
Los siguientes informes de defectos de cambio de comportamiento se aplicaron de manera retroactiva a los estándares de C++ publicados anteriormente.
| ID | Aplicado a | Comportamiento según lo publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 2039 | C++11 | Se requería que solo la expresión antes de la conversión fuera constante. |
La conversión también debe ser válida en una expresión constante. |
| P2593R1 | C++11 | static_assert(false, ""); sin instanciar estaba mal formada.
|
Se hizo bien formada. |
Referenciass
- El estándar C++23 (ISO/IEC 14882:2023):
- 9.1 Preámbulo [dcl.pre](p: 10)
- El estándar C++20 (ISO/IEC 14882:2020):
- 9.1 Preámbulo [dcl.pre](p: 6)
- El estándar C++17 (ISO/IEC 14882:2017):
- 10 Declaraciones [dcl.dcl](p: 6)
- El estándar C++14 (ISO/IEC 14882:2014):
- 7 Declaraciones [dcl.dcl](p: 4)
- El 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 quede mal formado.. (directiva de preprocesador) | |
Aborta el programa si la condición especificada por el usuario no es verdadera (true). Puede ser desactivada para las versiones de lanzamiento. (macro de función) | |
(C++11) |
Condicionalmente elimina una sobrecarga de función o especialización de plantilla de la resolución de sobrecargas. (plantilla de clase) |
| Rasgos de tipo (C++11) | Define interfaces basadas en plantillas de tiempo de compilación para consultar las propiedades de los tipos |
Documentación de C para Static assertion
| |