std:: variant
|
Definido en el encabezado
<variant>
|
||
|
template
<
class
...
Types
>
class variant ; |
(desde C++17) | |
La plantilla de clase
std::variant
representa una
union
type-safe.
Una instancia de
variant
en cualquier momento dado contiene un valor de uno de sus tipos alternativos, o en caso de error - ningún valor (este estado es difícil de alcanzar, ver
valueless_by_exception
).
Al igual que con las uniones, si una variante contiene un valor de algún tipo de objeto
T
, el objeto
T
está
anidado dentro
del objeto
variant
.
Una variante no puede contener referencias, arrays o el tipo void .
Se permite que una variante contenga el mismo tipo más de una vez, y que contenga versiones del mismo tipo con calificadores cv diferentes.
De manera consistente con el comportamiento de las uniones durante la inicialización por agregado , un variant construido por defecto contiene un valor de su primera alternativa, a menos que esa alternativa no sea construible por defecto (en cuyo caso el variant tampoco es construible por defecto). La clase auxiliar std::monostate puede utilizarse para hacer que dichos variants sean construibles por defecto.
Un programa que instancia la definición de
std::variant
sin argumentos de plantilla está mal formado.
std
::
variant
<
std::
monostate
>
puede ser utilizado en su lugar.
Si un programa declara una
especialización explícita
o una
especialización parcial
de
std::variant
, el programa está mal formado, no se requiere diagnóstico.
Contenidos |
Parámetros de plantilla
| Tipos | - | los tipos que pueden almacenarse en esta variante. Todos los tipos deben cumplir con los Destructible requisitos (en particular, los tipos array y los tipos no-objeto no están permitidos). |
Funciones miembro
construye el objeto
variant
(función miembro pública) |
|
destruye el
variant
, junto con su valor contenido
(función miembro pública) |
|
asigna un
variant
(función miembro pública) |
|
Observadores |
|
retorna el índice basado en cero de la alternativa contenida por el
variant
(función miembro pública) |
|
verifica si el
variant
está en estado inválido
(función miembro pública) |
|
Modificadores |
|
construye un valor en el
variant
, en el lugar
(función miembro pública) |
|
intercambia con otro
variant
(función miembro pública) |
|
Visitación |
|
|
(C++26)
|
llama al funtor proporcionado con el argumento contenido por el
variant
(función miembro pública) |
Funciones no miembro
|
(C++17)
|
llama al functor proporcionado con los argumentos contenidos en una o más
variant
s
(plantilla de función) |
|
(C++17)
|
comprueba si una
variant
contiene actualmente un tipo dado
(plantilla de función) |
|
(C++17)
|
lee el valor de la variant dado el índice o el tipo (si el tipo es único), lanza excepción en caso de error
(plantilla de función) |
|
(C++17)
|
obtiene un puntero al valor de una
variant
apuntada dado el índice o el tipo (si es único), retorna nulo en caso de error
(plantilla de función) |
|
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++17)
(C++20)
|
compara objetos
variant
como sus valores contenidos
(plantilla de función) |
|
(C++17)
|
especializa el algoritmo
std::swap
(plantilla de función) |
Clases auxiliares
|
(C++17)
|
tipo de marcador de posición para usar como primera alternativa en un
variant
de tipos no construibles por defecto
(clase) |
|
(C++17)
|
excepción lanzada en accesos inválidos al valor de un
variant
(clase) |
|
(C++17)
|
obtiene el tamaño de la lista de alternativas del
variant
en tiempo de compilación
(plantilla de clase) (plantilla de variable) |
|
obtiene el tipo de la alternativa especificada por su índice, en tiempo de compilación
(plantilla de clase) (plantilla de alias) |
|
|
(C++17)
|
soporte de hash para
std::variant
(especialización de plantilla de clase) |
Objetos auxiliares
|
(C++17)
|
índice del
variant
en estado inválido
(constante) |
Notas
| Macro de prueba de características | Valor | Std | Característica |
|---|---|---|---|
__cpp_lib_variant
|
201606L
|
(C++17) |
std::variant
: una unión type-safe
|
202102L
|
(C++23)
(DR17) |
std::visit
para clases derivadas de
std::variant
|
|
202106L
|
(C++23)
(DR20) |
Completamente
constexpr
std::variant
|
|
202306L
|
(C++26) |
Función miembro
visit
|
Ejemplo
#include <cassert> #include <iostream> #include <string> #include <variant> int main() { std::variant<int, float> v, w; v = 42; // v contiene int int i = std::get<int>(v); assert(42 == i); // tiene éxito w = std::get<int>(v); w = std::get<0>(v); // mismo efecto que la línea anterior w = v; // mismo efecto que la línea anterior // std::get<double>(v); // error: no hay double en [int, float] // std::get<3>(v); // error: los valores de índice válidos son 0 y 1 try { std::get<float>(w); // w contiene int, no float: lanzará excepción } catch (const std::bad_variant_access& ex) { std::cout << ex.what() << '\n'; } using namespace std::literals; std::variant<std::string> x("abc"); // los constructores de conversión funcionan cuando son unívocos x = "def"; // la asignación de conversión también funciona cuando es unívoca std::variant<std::string, void const*> y("abc"); // convierte a void const* cuando se pasa un char const* assert(std::holds_alternative<void const*>(y)); // tiene éxito y = "xyz"s; assert(std::holds_alternative<std::string>(y)); // tiene éxito }
Salida posible:
std::get: wrong index for variant
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.
| DR | Se aplica a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 2901 | C++17 |
se proporcionaba especialización de
std::uses_allocator
,
pero
variant
no puede soportar correctamente allocators
|
especialización eliminada |
| LWG 3990 | C++17 |
un programa podría declarar una especialización
explícita o parcial de
std::variant
|
el programa está mal formado en este
caso (no se requiere diagnóstico) |
| LWG 4141 | C++17 |
el requisito para asignación de
almacenamiento era confuso |
el objeto contenido debe estar
anidado dentro del objeto
variant
|
Véase también
|
etiqueta de construcción in-place
(etiqueta) |
|
|
(C++17)
|
un contenedor que puede o no contener un objeto
(plantilla de clase) |
|
(C++17)
|
objetos que contienen instancias de cualquier tipo
CopyConstructible
(clase) |