Namespaces
Variants

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

De es.cppreference.net
 
 
Biblioteca de utilidades
Soporte de lenguaje
Soporte de tipos (tipos básicos, RTTI)
Macros de prueba de características de la biblioteca (C++20)
Utilidades de programa
Funciones variádicas
Soporte de corrutinas (C++20)
Soporte de contratos (C++26)
Comparación de tres vías
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Utilidades generales
Operadores relacionales (obsoleto en C++20)
 
 
tuple& operator=( const tuple& other );
(1) (desde C++11)
(constexpr desde C++20)
constexpr const tuple& operator=( const tuple& other ) const;
(2) (desde C++23)
tuple& operator=( tuple&& other ) noexcept(/* see below */);
(3) (desde C++11)
(constexpr desde C++20)
constexpr const tuple& operator=( tuple&& other ) const;
(4) (desde C++23)
template< class... UTypes >
tuple& operator=( const tuple<UTypes...>& other );
(5) (desde C++11)
(constexpr desde C++20)
template< class... UTypes >
constexpr const tuple& operator=( const tuple<UTypes...>& other ) const;
(6) (desde C++23)
template< class... UTypes >
tuple& operator=( tuple<UTypes...>&& other );
(7) (desde C++11)
(constexpr desde C++20)
template< class... UTypes >
constexpr const tuple& operator=( tuple<UTypes...>&& other ) const;
(8) (desde C++23)
template< class E1, class E2 >
tuple& operator=( const std::pair<E1, E2>& p );
(9) (desde C++11)
(constexpr desde C++20)
template< class E1, class E2 >
constexpr const tuple& operator=( const std::pair<E1, E2>& p ) const;
(10) (desde C++23)
template< class E1, class E2 >
tuple& operator=( std::pair<E1, E2>&& p );
(11) (desde C++11)
(constexpr desde C++20)
template< class E1, class E2 >
constexpr const tuple& operator=( std::pair<E1, E2>&& p ) const;
(12) (desde C++23)
template< tuple-like UTuple >
constexpr tuple& operator=( UTuple&& u );
(13) (desde C++23)
template< tuple-like UTuple >
constexpr const tuple& operator=( UTuple&& u ) const;
(14) (desde C++23)

Reemplaza el contenido de la tupla con el contenido de otro objeto similar a una tupla.

En las descripciones siguientes, sea

  • i en el rango [​0​, sizeof...(Types)) en orden,
  • Ti sea el iésimo tipo en el paquete de parámetros de plantilla de clase Types, y
  • Ui sea el iésimo tipo en un paquete de parámetros de plantilla de función llamado UTypes,

donde la indexación es basada en cero.

1) Operador de asignación de copia. Asigna cada elemento de other al elemento correspondiente de *this.
Esta sobrecarga se define como eliminada a menos que std::is_copy_assignable<Ti>::value sea true para todo Ti.
2) Operador de asignación de copia para operando calificado como const. Asigna cada elemento de other al elemento correspondiente de *this.
Esta sobrecarga participa en la resolución de sobrecarga solo si std::is_copy_assignable_v<const Ti> es true para todo Ti.
3) Operador de asignación de movimiento. Para todo i, asigna std::forward<Ti>(std::get<i>(other)) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si std::is_move_assignable<Ti>::value es true para todo Ti.
4) Operador de asignación de movimiento para operando calificado como const. Para todo i, asigna std::forward<Ti>(std::get<i>(other)) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si std::is_assignable_v<const Ti&, Ti> es true para todo Ti.
5) Para todo i, asigna std::get<i>(other) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si sizeof...(Types) == sizeof...(UTypes), y std::is_assignable<Ti&, const Ui&>::value es true para todos los pares correspondientes de tipos Ti y Ui.
6) Para todo i, asigna std::get<i>(other) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si sizeof...(Types) == sizeof...(UTypes), y std::is_assignable_v<const Ti&, const Ui&> es true para todos los pares correspondientes de tipos Ti y Ui.
7) Para todo i, asigna std::forward<Ui>(std::get<i>(other)) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si sizeof...(Types) == sizeof...(UTypes), y std::is_assignable<Ti&, Ui>::value es true para todos los pares correspondientes de tipos Tiy Ui.
8) Para todo i, asigna std::forward<Ui>(std::get<i>(other)) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si sizeof...(Types) == sizeof...(UTypes), y std::is_assignable_v<const Ti&, Ui> es true para todos los pares correspondientes de tipos Ti y Ui.
9) Asigna p.first al primer elemento de *this y p.second al segundo elemento de *this.
Esta sobrecarga participa en la resolución de sobrecarga solo si
  • sizeof...(Types) == 2,
  • std::is_assignable<T0&, const E1&>::value es true, y
  • std::is_assignable<T1&, const E2&>::value es true.
10) Asigna p.first al primer elemento y p.second al segundo elemento.
Esta sobrecarga participa en la resolución de sobrecarga solo si
  • sizeof...(Types) == 2,
  • std::is_assignable_v<const T0&, const E1&> es true, y
  • std::is_assignable_v<const T1&, const E2&> es true.
11) Asigna std::forward<E1>(p.first) al primer elemento de *this y std::forward<E2>(p.second) al segundo elemento de *this.
Esta sobrecarga participa en la resolución de sobrecarga solo si
  • sizeof...(Types) == 2,
  • std::is_assignable_v<T0&, E1> es true, y
  • std::is_assignable_v<T1&, E2> es true.
12) Asigna std::forward<E1>(p.first) al primer elemento y std::forward<E2>(p.second) al segundo elemento.
Esta sobrecarga participa en la resolución de sobrecarga solo si
  • sizeof...(Types) == 2,
  • std::is_assignable_v<const T0&, E1> es true, y
  • std::is_assignable_v<const T1&, E2> es true.
13) Para todo i, asigna std::get<i>(std::forward<UTuple>(u)) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si
  • std::same_as<std::remove_cvref_t<UTuple>, std::tuple> es false,
  • std::remove_cvref_t<UTuple> no es una especialización de std::ranges::subrange,
  • sizeof...(Types) es igual a std::tuple_size_v<std::remove_cvref_t<UTuple>>, y
  • std::is_assignable_v<Ti&, decltype(std::get<i>(std::forward<UTuple>(u)))> es true para todo i.
14) Para todo i, asigna std::get<i>(std::forward<UTuple>(u)) a std::get<i>(*this).
Esta sobrecarga participa en la resolución de sobrecarga solo si
  • std::same_as<std::remove_cvref_t<UTuple>, std::tuple> es false,
  • std::remove_cvref_t<UTuple> no es una especialización de std::ranges::subrange,
  • sizeof...(Types) es igual a std::tuple_size_v<std::remove_cvref_t<UTuple>>, y
  • std::is_assignable_v<const Ti&, decltype(std::get<i>(std::forward<UTuple>(u)))> es true para todo i.

Parámetros

other - tupla cuyos contenidos reemplazarán los de esta tupla
p - par cuyos contenidos reemplazarán los de esta 2-tupla
u - tuple-like objeto cuyos contenidos reemplazarán los de esta tupla

Valor de retorno

* this

Excepciones

1,2) Puede lanzar excepciones definidas por la implementación si la asignación de uno de los tipos en Types lanza una excepción.
3)
noexcept especificación:
noexcept (

std:: is_nothrow_move_assignable < T0 > :: value &&
std:: is_nothrow_move_assignable < T1 > :: value &&
std:: is_nothrow_move_assignable < T2 > :: value &&
...

)
4-14) Puede lanzar excepciones definidas por la implementación si la asignación de uno de los tipos en Types lanza una excepción.

Ejemplo

#include <iostream>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
// función auxiliar para imprimir std::vector<int>
std::ostream& operator<<(std::ostream& os, std::vector<int> const& v)
{
    os << '{';
    for (std::size_t t = 0; t != v.size(); ++t)
        os << v[t] << (t + 1 < v.size() ? ", " : "");
    return os << '}';
}
// helpers para imprimir una tupla de cualquier tamaño
template<class... Args>
void print_tuple(std::string_view name, const std::tuple<Args...>& t)
{
    std::cout << name << " = {";
    std::apply([&](auto&& arg, auto&&... args)
    {
        std::cout << arg;
        ((std::cout << ", " << args), ...);
    }, t);
    std::cout << '}';
}
template<class Tuple1, class Tuple2>
void print_tuples(std::string_view name1, const Tuple1& t1,
                  std::string_view name2, const Tuple2& t2)
{
    print_tuple(name1, t1);
    std::cout << ", ";
    print_tuple(name2, std::tuple(t2));
    std::cout << "\n\n";
}
int main()
{
    // Ejemplos de tupla a tupla //
    std::tuple<int, std::string, std::vector<int>>
        t1{1, "alfa", {1, 2, 3}},
        t2{2, "beta", {4, 5}};
    print_tuples("1) t1", t1, "t2", t2);
    // Asignación de copia normal
    // operator=( const tuple& other );
    t1 = t2;
    print_tuples("2) t1 = t2;\n   t1", t1, "t2", t2);
    // Asignación de movimiento normal
    // operator=( tuple&& other );
    t1 = std::move(t2);
    print_tuples("3) t1 = std::move(t2);\n   t1", t1, "t2", t2);
    // Conversión de asignación de copia
    // operator=( const tuple<UTypes...>& other );
    std::tuple<short, const char*, std::vector<int>> t3{3, "gamma", {6, 7, 8}};
    t1 = t3;
    print_tuples("4) t1 = t3;\n   t1", t1, "t3", t3);
    // Asignación de movimiento de conversión
    // operator=( tuple<UTypes...>&& other );
    t1 = std::move(t3);
    print_tuples("5) t1 = std::move(t3);\n   t1", t1, "t3", t3);
    // Ejemplos de par a tupla //
    std::tuple<std::string, std::vector<int>> t4{"delta", {10, 11, 12}};
    std::pair<const char*, std::vector<int>> p1{"épsilon", {14, 15, 16}};
    print_tuples("6) t4", t4, "p1", p1);
    // Conversión de asignación de copia desde std::pair
    // operator=( const std::pair<U1, U2>& p );
    t4 = p1;
    print_tuples("7) t4 = p1;\n   t4", t4, "p1", p1);
    // Conversión de asignación de movimiento desde std::pair
    // operator=( std::pair<U1, U2>&& p );
    t4 = std::move(p1);
    print_tuples("8) t4 = std::move(p1);\n   t4", t4, "p1", p1);
}

Salida posible:

1) t1 = {1, alpha, {1, 2, 3}}, t2 = {2, beta, {4, 5}}
2) t1 = t2;
   t1 = {2, beta, {4, 5}}, t2 = {2, beta, {4, 5}}
3) t1 = std::move(t2);
   t1 = {2, beta, {4, 5}}, t2 = {2, , {}}
4) t1 = t3;
   t1 = {3, gamma, {6, 7, 8}}, t3 = {3, gamma, {6, 7, 8}}
5) t1 = std::move(t3);
   t1 = {3, gamma, {6, 7, 8}}, t3 = {3, gamma, {}}
6) t4 = {delta, {10, 11, 12}}, p1 = {epsilon, {14, 15, 16}}
7) t4 = p1;
   t4 = {epsilon, {14, 15, 16}}, p1 = {epsilon, {14, 15, 16}}
8) t4 = std::move(p1);
   t4 = {epsilon, {14, 15, 16}}, p1 = {epsilon, {}}

Informes de defectos

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

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2729 C++11 operator = no tenía restricciones y podría
resultar en comportamiento indefinido innecesario
con restricciones

Véase también

construye un nuevo tuple
(función miembro pública)
asigna los contenidos
(función miembro pública de std::pair<T1,T2> )