constexprvariant()noexcept(/* see below */);
(1) (desde C ++ 17)
constexprvariant(const variant& other);
(2) (desde C ++ 17)
constexprvariant(variant&& other)noexcept(/* see below */);
(3) (desde C ++ 17)
template<classT>constexprvariant(T&& t)noexcept(/* see below */);
(4) (desde C ++ 17)
template<classT,class... Args >constexprexplicitvariant(std::in_place_type_t<T>, Args&&... args);
(5) (desde C ++ 17)
template<classT,classU,class... Args >constexprexplicitvariant(std::in_place_type_t<T>,
                           std::initializer_list<U> il, Args&&... args);
(6) (desde C ++ 17)
template< std::size_t I,class... Args >constexprexplicitvariant(std::in_place_index_t<I>, Args&&... args);
(7) (desde C ++ 17)
template< std::size_t I,classU,class... Args >constexprexplicitvariant(std::in_place_index_t<I>,
                           std::initializer_list<U> il, Args&&... args);
(8) (desde C ++ 17)

Construye un nuevo variant objeto.

1) Constructor predeterminado. Construye una variante que contiene el valor inicializado de valor de la primera alternativa (index() es cero). Este constructor es constexpr si y solo si la inicialización del valor del tipo alternativo T_0 satisfaría los requisitos para una función constexpr. Esta sobrecarga solo participa en la resolución de la sobrecarga si std::is_default_constructible_v<T_0> es verdad.2) Copiar constructor. Si other no es valueless_by_exception, construye una variante con la misma alternativa que other e inicializa directamente el valor contenido con std::get(other). De lo contrario, inicializa una variante valueless_by_exception. Este constructor se define como eliminado a menos que std::is_copy_constructible_v<T_i> es cierto para todos T_i en Types.... Es trivial si std::is_trivially_copy_constructible_v<T_i> es cierto para todos T_i en Types....3) Mover constructor. Si other no es valueless_by_exception, construye una variante con la misma alternativa que other e inicializa directamente el valor contenido con std::get(std::move(other)). De lo contrario, inicializa un valueless_by_exception variante. Esta sobrecarga solo participa en la resolución de la sobrecarga si std::is_move_constructible_v<T_i> es cierto para todos T_i en Types.... Es trivial si std::is_trivially_move_constructible_v<T_i> es cierto para todos T_i en Types....4) Conversión de constructor. Construye una variante que contiene el tipo alternativo. T_j que se seleccionaría por resolución de sobrecarga para la expresión F(std::forward<T>(t)) si hubiera una sobrecarga de función imaginaria F(T_i) para cada T_i de Types... en el alcance al mismo tiempo, excepto que:

  • Una sobrecarga F(T_i) solo se considera si la declaración T_i x[]=std::forward<T>(t); es válido para alguna variable inventada x;
  • Si T_i es (posiblemente calificado para cv) bool, F(T_i) solo se considera si std:remove_cvref_t es también bool.

Inicializa directamente el valor contenido como si fuera una inicialización directa sin lista de std::forward<T>(t). Esta sobrecarga solo participa en la resolución de la sobrecarga si sizeof...(Types) > 0, std::decay_t<U>(hasta C ++ 20)std::remove_cvref_t<U>(desde C ++ 20) no es del mismo tipo que variant, ni una especialización de std::in_place_type_t, ni una especialización de std::in_place_index_t, std::is_constructible_v<T_j, T> es truey la expresión F(std::forward<T>(t)) (siendo F el conjunto de funciones imaginarias mencionado anteriormente) está bien formado. Este constructor es un constructor constexpr si el constructor seleccionado de T_j es un constructor constexpr.

std::variant<std::string>v("abc");// OK
std::variant<std::string, std::string>w("abc");// ill-formed
std::variant<std::string,constchar*>x("abc");// OK, chooses const char*
std::variant<std::string,bool>y("abc");// OK, chooses string; bool is not a candidate
std::variant<float,long,double> z =0;// OK, holds long// float and double are not candidates

5) Construye una variante con la alternativa especificada. T e inicializa el valor contenido con los argumentos std::forward<Args>(args).... Si el constructor seleccionado de T es un constructor constexpr, este constructor también es un constructor constexpr. Esta sobrecarga solo participa en la resolución de la sobrecarga si hay exactamente una ocurrencia de T en Types... y std::is_constructible_v<T, Args...> es true.6) Construye una variante con la alternativa especificada. T e inicializa el valor contenido con los argumentos il, std::forward<Args>(args)..... Si el constructor seleccionado de T es un constructor constexpr, este constructor también es un constructor constexpr. Esta sobrecarga solo participa en la resolución de la sobrecarga si hay exactamente una ocurrencia de T en Types... y std::is_constructible_v<T, initializer_list<U>&, Args...> es true.7) Construye una variante con la alternativa T_i especificada por el índice. I e inicializa el valor contenido con los argumentos std::forward<Args>(args).... Si el constructor seleccionado de T_i es un constructor constexpr, este constructor también es un constructor constexpr. Esta sobrecarga solo participa en la resolución de la sobrecarga si I < sizeof...(Types) y std::is_constructible_v<T_i, Args...> es verdad. 8) Construye una variante con la alternativa T_i especificada por el índice. I e inicializa el valor contenido con los argumentos il, std::forward<Args>(args).... Si el constructor seleccionado de T_i es un constructor constexpr, este constructor también es un constructor constexpr. Esta sobrecarga solo participa en la resolución de la sobrecarga si I < sizeof...(Types) y std::is_constructible_v<T_i, std::initializer_list<U>&, Args...> es verdad.

Parámetros

otro - otro variant objeto cuyo valor contenido para copiar / mover
t - valor para inicializar el valor contenido con
argumentos ... - argumentos para inicializar el valor contenido con
Illinois - lista de inicializadores para inicializar el valor contenido con

Excepciones

1) Puede lanzar cualquier excepción generada por la inicialización de valor de la primera alternativa. noexcept especificación: noexcept(std::is_nothrow_default_constructible_v<T_0>)2) Puede lanzar cualquier excepción lanzada al inicializar directamente cualquier T_i en Types...3) Puede lanzar cualquier excepción lanzada al mover-construir cualquier T_i en Types.... noexcept especificación: noexcept((std::is_nothrow_move_constructible_v<Types>&& ...))4) Puede lanzar cualquier excepción lanzada por la inicialización de la alternativa seleccionada T_j. noexcept especificación: noexcept(std::is_nothrow_constructible_v<T_j, T>)5-8) Puede lanzar cualquier excepción lanzada llamando al constructor seleccionado de la alternativa seleccionada

Informes de defectos

Los siguientes informes de defectos que cambian el comportamiento se aplicaron retroactivamente a los estándares C ++ publicados anteriormente.

DR Aplicado a Comportamiento según lo publicado Comportamiento correcto
LWG 2901 C ++ 17 constructores con reconocimiento de asignadores proporcionados pero variant no puede apoyar adecuadamente a los asignadores constructores eliminados
P0739R0 C ++ 17 la conversión de la plantilla del constructor interactúa mal con la deducción del argumento de la plantilla de clase restricción agregada
LWG 3024 C ++ 17 el constructor de copias no participa en la resolución de sobrecargas si algún tipo de miembro no se puede copiar definido como eliminado en su lugar
P0602R4 C ++ 17 Los constructores de copiar / mover pueden no ser triviales incluso si los constructores subyacentes son triviales requerido para propagar la trivialidad
P0608R3 C ++ 17 El constructor convertidor ensambla ciegamente un conjunto de sobrecarga, lo que lleva a conversiones no deseadas. conversiones de restricción y booleanas no consideradas

Ejemplo