Espacios de nombres
Variantes
Acciones
 
 
Biblioteca de servicios
 
 
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)
Comprueba si el variante actualmente mantiene un tipo dado.
(plantilla de función)
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)
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)
Excepción lanzada durante accesos inválidos al valor de un variante.
(clase)
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)
Especializa el algoritmo std::hash.
(especialización de plantilla de clase)

Objetos auxiliares

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

variant no puede soportar asignadores apropiadamente.

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)