std::variant<Types...>:: variant
|
constexpr
variant
(
)
noexcept
(
/* ver más abajo */
)
;
|
(1) | (desde C++17) |
|
constexpr
variant
(
const
variant
&
other
)
;
|
(2) | (desde C++17) |
|
constexpr
variant
(
variant
&&
other
)
noexcept
(
/* ver más abajo */
)
;
|
(3) | (desde C++17) |
|
template
<
class
T
>
constexpr variant ( T && t ) noexcept ( /* ver más abajo */ ) ; |
(4) | (desde C++17) |
|
template
<
class
T,
class
...
Args
>
|
(5) | (desde C++17) |
|
template
<
class
T,
class
U,
|
(6) | (desde C++17) |
|
template
<
std::
size_t
I,
class
...
Args
>
|
(7) | (desde C++17) |
|
template
<
std::
size_t
I,
class
U,
|
(8) | (desde C++17) |
Construye un nuevo
variant
objeto.
variant
que contiene el valor
inicializado por defecto
de la primera alternativa (
index()
es cero).
-
Este constructor es
constexpr
si y solo si la inicialización por defecto del tipo alternativo
T_0cumpliría con los requisitos para una función constexpr . - Esta sobrecarga participa en la resolución de sobrecarga solo si std:: is_default_constructible_v < T_0 > es true .
variant
que contiene la misma alternativa que
other
e
inicializa directamente
el valor contenido con
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
. De lo contrario, inicializa un variant
valueless_by_exception
.
-
Este constructor se define como eliminado a menos que
std::
is_copy_constructible_v
<
T_i
>
sea
true
para todos los
T_ien Types... . -
Es trivial si
std::
is_trivially_copy_constructible_v
<
T_i
>
es
true
para todos los
T_ien Types... .
variant
que contiene la misma alternativa que
other
e
inicializa directamente
el valor contenido con
std
::
move
(
*
std::
get_if
<
other.
index
(
)
>
(
std::
addressof
(
other
)
)
)
. De lo contrario, inicializa un variant
valueless_by_exception
.
-
Esta sobrecarga participa en la resolución de sobrecarga solo si
std::
is_move_constructible_v
<
T_i
>
es
true
para todos los
T_ien Types... . -
Es trivial si
std::
is_trivially_move_constructible_v
<
T_i
>
es
true
para todos los
T_ien Types... .
variant
que contiene el tipo alternativo
T_j
que sería seleccionado por la resolución de sobrecarga para la expresión
F
(
std::
forward
<
T
>
(
t
)
)
si existiera una sobrecarga de función imaginaria
F(T_i)
para cada
T_i
en
Types...
, excepto que no se consideran conversiones que impliquen estrechamiento.
Formalmente:
-
-
Una sobrecarga
F
(
T_i
)
solo se considera si la declaración
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
es válida para alguna variable inventada
x.
-
Una sobrecarga
F
(
T_i
)
solo se considera si la declaración
T_i x
[
]
=
{
std::
forward
<
T
>
(
t
)
}
;
es válida para alguna variable inventada
-
Esta sobrecarga participa en la resolución de sobrecarga solo si
- sizeof... ( Types ) > 0 ,
-
std::
decay_t
<
T
>
(hasta C++20)
std::
remove_cvref_t
<
T
>
(desde C++20)
no es ni 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 true ,
- y la expresión F ( std:: forward < T > ( t ) ) (con F siendo el conjunto mencionado anteriormente de funciones imaginarias) está bien formada.
-
Este constructor es un constructor
constexpr
si el constructor seleccionado de
T_jes un constructor constexpr.
std::variant<std::string> v("abc"); // OK std::variant<std::string, std::string> w("abc"); // incorrecto std::variant<std::string, const char*> x("abc"); // OK, elige const char* std::variant<std::string, bool> y("abc"); // OK, elige string; bool no es candidato std::variant<float, long, double> z = 0; // OK, contiene long // float y double no son candidatos
variant
con la alternativa especificada
T
e inicializa el valor contenido con los argumentos
std::
forward
<
Args
>
(
args
)
...
.
-
Si el constructor seleccionado de
Tes un constructor constexpr , este constructor también es un constructor constexpr . -
Esta sobrecarga participa en la resolución de sobrecarga solo si hay exactamente una ocurrencia de
Ten Types... y std:: is_constructible_v < T, Args... > es true .
variant
con la alternativa especificada
T
e inicializa el valor contenido con los argumentos
il,
std::
forward
<
Args
>
(
args
)
...
.
-
Si el constructor seleccionado de
Tes un constructor constexpr , este constructor también es un constructor constexpr . -
Esta sobrecarga participa en la resolución de sobrecarga solo si hay exactamente una ocurrencia de
Ten Types... y std:: is_constructible_v < T, initializer_list < U > & , Args... > es true .
variant
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_ies un constructor constexpr , este constructor también es un constructor constexpr . - Esta sobrecarga participa en la resolución de sobrecarga solo si I < sizeof... ( Types ) y std:: is_constructible_v < T_i, Args... > es true .
variant
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_ies un constructor constexpr , este constructor también es un constructor constexpr . - Esta sobrecarga participa en la resolución de sobrecarga solo si I < sizeof... ( Types ) y std:: is_constructible_v < T_i, std:: initializer_list < U > & , Args... > es true .
Contenidos |
Parámetros
| other | - |
otro objeto
variant
cuyo valor contenido copiar/mover
|
| t | - | valor para inicializar el valor contenido |
| args... | - | argumentos para inicializar el valor contenido |
| il | - | lista de inicialización para inicializar el valor contenido |
Excepciones
T_i
en
Types...
.
T_i
en
Types...
.
T_j
.
Notas
MSVC STL inicialmente trató P0608R3 como un cambio en C++20. A partir de VS 2022 17.12, MSVC STL también trata P0608R3 como un informe de defectos contra C++17.
Ejemplo
#include <cassert> #include <iostream> #include <string> #include <variant> #include <vector> using vector_t = std::vector<int>; auto& operator<<(auto& out, const vector_t& v) { out << "{ "; for (int e : v) out << e << ' '; return out << '}'; } int main() { // inicializa por valor la primera alternativa std::variant<int, std::string> var0; assert(std::holds_alternative<int>(var0) and var0.index() == 0 and std::get<int>(var0) == 0); // inicializa la primera alternativa con std::string{"STR"}; std::variant<std::string, int> var1{"STR"}; assert(var1.index() == 0); std::cout << "1) " << std::get<std::string>(var1) << '\n'; // inicializa la segunda alternativa con int == 42; std::variant<std::string, int> var2{42}; assert(std::holds_alternative<int>(var2)); std::cout << "2) " << std::get<int>(var2) << '\n'; // inicializa la primera alternativa con std::string{4, 'A'}; std::variant<std::string, vector_t, float> var3 { std::in_place_type<std::string>, 4, 'A' }; assert(var3.index() == 0); std::cout << "3) " << std::get<std::string>(var3) << '\n'; // inicializa la segunda alternativa con std::vector{1,2,3,4,5}; std::variant<std::string, vector_t, char> var4 { std::in_place_type<vector_t>, {1, 2, 3, 4, 5} }; assert(var4.index() == 1); std::cout << "4) " << std::get<vector_t>(var4) << '\n'; // inicializa la primera alternativa con std::string{"ABCDE", 3}; std::variant<std::string, vector_t, bool> var5 {std::in_place_index<0>, "ABCDE", 3}; assert(var5.index() == 0); std::cout << "5) " << std::get<std::string>(var5) << '\n'; // inicializa la segunda alternativa con std::vector(4, 42); std::variant<std::string, vector_t, char> var6 {std::in_place_index<1>, 4, 42}; assert(std::holds_alternative<vector_t>(var6)); std::cout << "6) " << std::get<vector_t>(var6) << '\n'; }
Salida:
1) STR
2) 42
3) AAAA
4) { 1 2 3 4 5 }
5) ABC
6) { 42 42 42 42 }
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 2901 | C++17 |
constructores conscientes del asignador proporcionados pero
variant
no puede soportar adecuadamente asignadores
|
constructores eliminados |
| P0739R0 | C++17 |
la plantilla del constructor de conversión interactúa
deficientemente con la deducción de argumentos de plantilla de clase |
restricción añadida |
| LWG 3024 | C++17 |
el constructor de copia no participa en la
resolución de sobrecarga si algún tipo miembro no es copiable |
definido como eliminado en su lugar |
| P0602R4 | C++17 |
los constructores de copia/movimiento pueden no ser
triviales incluso si los constructores subyacentes son triviales |
requerido propagar trivialidad |
| P0608R3 | C++17 |
el constructor de conversión ensambla ciegamente
un conjunto de sobrecarga, conduciendo a conversiones no intencionadas |
conversiones de estrechamiento y booleanas no consideradas |
| P1957R2 | C++17 |
el constructor de conversión para
bool
no permitía
conversión implícita |
La conversión de puntero a
bool
es de estrechamiento y
el constructor de conversión no tiene excepción para bool |