Namespaces
Variants

std:: variant

From cppreference.net
Utilities library
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)
comprueba si una variant contiene actualmente un tipo dado
(plantilla de función)
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)
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)
excepción lanzada en accesos inválidos al valor de un variant
(clase)
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)
soporte de hash para std::variant
(especialización de plantilla de clase)

Objetos auxiliares

í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)