std::variant
| Definido en el archivo de encabezado <variant>
|
||
template <typename... Types> class variant; |
(desde C++17) | |
La plantilla de clase std::variant representa un tipo variante: una union de tipo seguro. Una instancia de std::variant en cualquier tiempo dado mantiene ya sea o valor a uno de sus tipos alternos, 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 un variante tiene un valor de algún tipo de objeto T, la representación del objeto de T se asigna directamente dentro de la representación del objeto del variante mismo. El variante no tiene permitido asignar memoria adicional (dinámica).
No se permite que un variante contenga referencias, arrays o el tipo void. Los variantes vacíos también están mal formados (std::variant<std::monostate> puede usarse en su lugar).
Se permite que un variante contenga el mismo tipo más de una vez, y que contenga versiones calificadas-cv diferentes del mismo tipo.
De acuerdo con el comportamiento de las uniones durante inicialización de agregado, un variante construido por defecto tiene un valor de su primera alternativa, a menos que esa alternativa no sea construible por defecto (en cuyo caso el variante tampoco es construible por defecto). La clase auxiliar std::monostate puede usarse para hacer que tales variantes sean construibles por defecto.
Parámetros de plantilla
| Types | - | Los tipos que pueden almacenarse en este variante. Todos los tipos deben cumplir con los requisitos Destructible (en particular, los tipos de array y los tipos no objeto no están permitidos). |
Funciones miembro
| Construye el objeto variante. (función miembro pública) | |
| Destruye el variante, así como su valor contenido. (función miembro pública) | |
| Asigna un variante. (función miembro pública) | |
Observadores | |
| Devuelve el subíndice de base cero de la alternativa mantenida por el variante. (función miembro pública) | |
| Comprueba si el variante se encuentra en el estado inválido. (función miembro pública) | |
Modificadores | |
| Construye un valor en el variante, en el sitio. (función miembro pública) | |
| Intercambia con otro variante. (función miembro pública) | |
Funciones no miembro
(C++17) |
Llama al objeto función proporcionado con los argumentos mantenidos por uno o más variantes. (plantilla de función) |
(C++17) |
Comprueba si el variante actualmente mantiene un tipo dado. (plantilla de función) |
(C++17) |
Lee el valor del variante dado el subíndice o el tipo (si el tipo es único), lanza una excepción si existe un error. (plantilla de función) |
(C++17) |
Obtiene un puntero al valor de un variante al que se apunta dado el subíndice del tipo (si es único), devuelve nulo cuando existe un error. (plantilla de función) |
(C++17)(C++17)(C++17)(C++17)(C++17)(C++17)(C++20) |
Compara objetos variant con sus valores contenidos. (plantilla de función) |
(C++17) |
Especializa el algoritmo std::swap. (función) |
Clases auxiliares
(C++17) |
Tipo de marcador de posición para usarse como la primer alternativa en un variante de tipos no construibles por defecto. (clase) |
(C++17) |
Excepción lanzada durante accesos inválidos al valor de un variante. (clase) |
(C++17) |
Obtiene el tamaño de la lista de alternativas del variante en tiempo de compilación. (plantilla de clase) (plantilla de variables) |
| Obtiene el tipo de la alternativa dado su subíndice, en tiempo de compilación. (plantilla de clase) (plantilla de alias) | |
(C++17) |
Especializa el algoritmo std::hash. (especialización de plantilla de clase) |
Objetos auxiliares
(C++17) |
Subíndice del variante en el estado inválido. (constante) |
Ejemplo
#include <variant>
#include <string>
#include <cassert>
#include <iostream>
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); // el mismo efecto que la línea anterior
w = v; // el mismo efecto que la línea anterior
// std::get<double>(v); // ERROR: no hay un double en [int, float]
// std::get<3>(v); // ERROR: valores válidos de subíndices son 0 y 1
try {
std::get<float>(w); // w contiene int, no float: lanzará
}
catch (const std::bad_variant_access& ex) {
std::cout << ex.what() << '\n';
}
using namespace std::literals;
std::variant<std::string> x("abc");
// constructores de conversión funcionan cuando existe ambigüedad
x = "def"; // asignación de conversión también funciona cuando existe ambigüedad
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
}
Posible salida:
std::get: wrong index for variant
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 |
|---|---|---|---|
| LWG 2901 | C++17 | La especialización de std::uses_allocator se proporciona, pero
|
Se eliminó la especialización. |
Véase también
| Etiqueta de construcción en el sitio (in situ). (plantilla de clase) | |
(C++17) |
Un envoltorio que puede o no mantener un objeto. (plantilla de clase) |
(C++17) |
Objetos que contienen instancias de cualquier tipo CopyConstructible. (clase) |