Espacios de nombres
Variantes
Acciones

std::variant<Types...>::operator=

De cppreference.com
< cpp‎ | utility‎ | variant
 
 
Biblioteca de servicios
 
 
constexpr variant& operator=(const variant& rhs );
(1) (desde C++17)
constexpr variant& operator=( variant&& rhs )noexcept(/* véase más abajo */);
(2) (desde C++17)
template<class T >
variant& operator=( T&& t )noexcept(/* véase más abajo */);
(3) (desde C++17)

Asigna un valor nuevo a un objeto variant existente.

1) Asignación de copia:
  • Si tanto *this como rhs están sin valor por excepción, no hace nada.
  • De lo contrario, si rhs está sin valor, pero *this no, destruye el valor contenido en *this y lo hace sin valor.
  • De lo contrario, si rhs mantiene la misma alternativa que *this, asigna el valor contenido en rhs al valor contenido en *this. Si se lanza una excepción, *this no se vuelve sin valor: el valor depende de la garantía de seguridad de excepción de la asignación de copia de la alternativa.
  • De lo contrario, si la alternativa mantenida por rhs es o bien construible por copia que no lanza o no construible por movimiento que no lanza (determinado por std::is_nothrow_copy_constructible y std::is_nothrow_move_constructible, respectivamente), es equivalente a this->emplace<rhs.index()>(get<rhs.index()>(rhs)).
  • De lo contrario, es equivalente a this->operator=(variant(rhs)). Observa que *this puede conventirse en valueless_by_exception como se describe en (2).
Esta sobrecarga se define como eliminada a menos que std::is_copy_constructible_v<T_i> y std::is_copy_assignable_v<T_i> sean ambas true para toda T_i en Types.... Esta sobrecarga es trivial si std::is_trivially_copy_constructible_v<T_i>,std::is_trivially_copy_assignable_v<T_i> y std::is_trivially_destructible_v<T_i> son todas true para toda T_i en Types....
2) Asignación de movimiento:
  • Si tanto *this como rhs están sin valor por excepción, no hace nada.
  • De lo contrario, si rhs está sin valor, pero *this no, destruye el valor contenido en *this y lo hace sin valor.
  • De lo contrario, si rhs mantiene la misma alternativa que *this, asigna std::get<j>(std::move(rhs)) al valor contenido en *this, con j siendo index(). Si se lanza una excepción, *this no se vuelve sin valor: el valor depende de la garantía de seguridad de excepción de la asignación de movimiento de la alternativa.
  • De lo contrario (si rhs y *this mantienen distintas alternativas), es equivalente a this->emplace<rhs.index()>(get<rhs.index()>(std::move(rhs))). Si se lanza una excepción por el constructor de movimiento de T_i, *this se vuelve valueless_by_exception.
Esta sobrecarga solo participa en la resolución de sobrecargas si std::is_move_constructible_v<T_i> y std::is_move_assignable_v<T_i> son ambas true para toda T_i en Types.... Esta sobrecarga es trivial si std::is_trivially_move_constructible_v<T_i>, std::is_trivially_move_assignable_v<T_i>, y std::is_trivially_destructible_v<T_i> son todas true para toda T_i en Types....
3) Asignación de conversión.
  • Determina el tipo alternaativo T_j que se seleccionaría por la resolución de sobrecarga para la expresión F(std::forward<T>(t)) si hubiera una sobrecarga de la función imaginaria F(T_i) para toda T_i de Types... en ámbito al mismo tiempo, excepto que:
  • Una sobrecarga F(T_i) solamente se considera si la declaración T_i x[]={std::forward<T>(t)}; es válida para alguna variable inventada x;
  • Si T_i es (posiblemente calificada-cv) bool, F(T_i) solamente se considera si std:remove_cvref_t<T> también es bool.
Esta sobrecarga solo participa en la resolución de sobrecargas si std::decay_t<T>(hasta C++20)std::remove_cvref_t<T>(desde C++20) no es el mismo tipo que variant y std::is_assignable_v<T_j&, T> es true y std::is_constructible_v<T_j, T> es true y la expresión F(std::forward<T>(t)) (con F siendo el conjunto de funciones imaginarias mencionadas previamente) está bien formada.
std::variant<string> v1; v1 ="abc";// de acuerdostd::variant<std::string, std::string> v2; v2 ="abc";// ERRORstd::variant<std::string, bool> v3; v3 ="abc";// de acuerdo, escoge string; bool no es un candidatostd::variant<float, long, double> v4;// mantiene float v4 =0;// de acuerdo, mantiene long; float y double no son candidatos

Contenido

[editar]Parámetros

rhs - Otro variante.
t - Un valor convertible a una de las alternativas del variante.

[editar]Valor de retorno

*this

[editar]Excepciones

1) Puede lanzar cualquier excepción lanzada por la asignación y la inicialización de copia/movimiento de cualquier alternativa.
2)
Especificación noexcept:   (desde C++11)
3)
Especificación noexcept:   (desde C++11)

[editar]Ejemplo

#include <iomanip>#include <iostream>#include <string>#include <type_traits>#include <variant>   std::ostream& operator<<(std::ostream& os, std::variant<int, std::string>const& va){ os <<": { ";   std::visit([&](auto&& arg){using T =std::decay_t<decltype(arg)>;ifconstexpr(std::is_same_v<T, int>) os << arg;elseifconstexpr(std::is_same_v<T, std::string>) os <<std::quoted(arg);}, va);   return os <<" };\n";}   int main(){std::variant<int, std::string> a{2017}, b{"CppCon"};std::cout<<"a"<< a <<"b"<< b <<'\n';   std::cout<<"(1) operator=( const variant& rhs )\n"; a = b;std::cout<<"a"<< a <<"b"<< b <<'\n';   std::cout<<"(2) operator=( variant&& rhs )\n"; a = std::move(b);std::cout<<"a"<< a <<"b"<< b <<'\n';   std::cout<<"(3) operator=( T&& t ), donde T es int\n"; a =2019;std::cout<<"a"<< a <<'\n';   std::cout<<"(3) operator=( T&& t ), donde T es std::string\n";std::string s{"CppNow"};std::cout<<"s: "<<std::quoted(s)<<'\n'; a = std::move(s);std::cout<<"a"<< a <<"s: "<<std::quoted(s)<<'\n';}

Posible salida:

a: { 2017 }; b: { "CppCon" };   (1) operator=( const variant& rhs ) a: { "CppCon" }; b: { "CppCon" };   (2) operator=( variant&& rhs ) a: { "CppCon" }; b: { "" };   (3) operator=( T&& t ), donde T es int a: { 2019 };   (3) operator=( T&& t ), donde T es std::string s: "CppNow" a: { "CppNow" }; s: ""

[editar]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 3024 C++17 El operador de asignación de copia no participa en la resolución de sobrecarga si cualquier tipo miembro no es copiable. En su lugar, se definió como eliminado.
P0602R4 C++17 La asignación de copia/movimiento puede no ser trivial incluso si las operaciones subyacentes son triviales. Se requirió que se propagase la trivialidad.
P0608R3 C++17 La asignación de conversión ciegamente recopila el conjunto de sobrecargas, lo que conduce a conversiones no deseadas. No se consideran las conversiones de estrechamiento ni Booleanas.

[editar]Véase también

Construye un valor en el variante, en el sitio.
(función miembro pública)[editar]
close