std::variant
| Definido en el encabezado <variant>
|
||
template< class... Types >
class variant;
|
(desde C++17) | |
La plantilla de clase std::variant representa una unión segura en cuanto a tipos.
Una instancia de variant en cualquier momento dado contiene un valor de uno de sus tipos alternativos, o en el caso de error, ningún valor (este estado es difícil de alcanzar, véase valueless_by_exception).
Al igual que con las uniones, si una variant contiene un valor de algún tipo de objeto T, el objeto T está anidado dentro del objeto variant.
No se permite que una variant contenga referencias, arreglos o el tipo void.
Se permite que una variant contenga el mismo tipo más de una vez, y que contenga versiones con diferentes calificadores cv del mismo tipo.
De acuerdo con el comportamiento de las uniones durante la inicialización agregada, una variant construida por defecto contiene un valor de su primera alternativa, a menos que esa alternativa no se pueda construir por defecto (en cuyo caso la variant tampoco se puede construir por defecto). La clase auxiliar std::monostate se puede usar para hacer que dichas variants se puedan construir por defecto.
Un programa que crea una instancia de la definición de std::variant sin argumentos de plantilla está mal formado. Se puede usar std::variant<std::monostate> en su lugar.
Si un programa declara una especialización explícita o parcial de std::variant, el programa está mal formado, no se requiere diagnóstico.
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) |