close
Пространства имён
Варианты
Действия

std::set::operator=

Материал из cppreference.com
 
 
 
std::set
Функции-элементы
Итераторы
Ёмкость
Модификаторы
(C++17)
Просмотр
Наблюдатели
Функции, не являющиеся элементами
(C++20)
(до C++20)(до C++20)(до C++20)(до C++20)(до C++20)(C++20)
Принципы вывода (C++17)
 
<tbody> </tbody> <tbody class="t-dcl-rev t-dcl-rev-num "> </tbody><tbody> </tbody>
set& operator=( const set& other );
(1)
(2)
set& operator=( set&& other );
(начиная с C++11)
(до C++17)
set& operator=( set&& other ) noexcept(/* смотрите ниже */);
(начиная с C++17)
set& operator=( std::initializer_list<value_type> ilist );
(3) (начиная с C++11)

Заменяет содержимое контейнера

1) Оператор присваивания копированием. Заменяет текущее содержимое копией содержимого other. Если std::allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value равняется true, то аллокатор текущего контейнера заменяется копией аллокатора присваиваемого. Если текущий аллокатор не равен присваиваемому, то аллокатор из *this используется для освобождения памяти, а затем аллокатор из other используется для выделения памяти перед копированием элементов. (начиная с C++11).
2) Оператор присваивания перемещением. Заменяет текущее содержимое содержимым other, используя семантику переноса (т.е. данные перемещаются из other в этот контейнер). После данной операции other находится в корректном, но неопределенном состоянии. Если std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value равно true, то аллокатор текущего контейнера заменяется копией аллокатора присваиваемого. Если же это значение false и аллокаторы текущего и присваиваемого контейнера не равны, то, поскольку текущий контейнер не может завладеть памятью присваиваемого, он вынужден присвоить перемещением каждый элемент по отдельности, выделяя дополнительную память с помощью своего аллокатора если потребуется. В любом случае все элементы изначально находящиеся в *this либо уничтожаются либо заменяются путём поэлементного присваивания.
3) Заменяет текущее содержимое содержимым ilist.

Параметры

other другой контейнер, используемый как источник данных
ilist список инициализаторов, используемый как источник данных

Возвращаемое значение

*this

Сложность

1) Линейная от размера *this и other.
2) Линейная от размера *this, помимо случая, когда аллокаторы не равны и не распространяются при присваивании, в котором линейная от размера *this и other.
3) O(NlogN) в обычном случае, где N равняется size() + ilist.size(). Линейная если ilist - отсортирован согласно value_comp().


Исключения

2)
спецификация noexcept:  
noexcept(std::allocator_traits<Allocator>::is_always_equal::value && std::is_nothrow_move_assignable<Compare>::value)
(начиная с C++17)

Примечания

После присвоения перемещением (перегрузка (2)), помимо случая, когда поэлементное присвоение произошло по причине несовместимых аллокаторов, ссылки, указатели и итераторы (кроме end итератора) из other остаются корректными, но ссылаются на элементы, которые теперь находятся в *this. Текущий стандарт даёт такую гарантию согласно общему утверждению из [container.requirements.general]/12, более прямая гарантия рассматривается в [lwg-2321].


Пример

Код ниже использует operator= для того, чтобы присвоить один std::set другому:

#include <set>
#include <iostream>

void display_sizes(char const* comment,
                   const std::set<int>& nums1,
                   const std::set<int>& nums2,
                   const std::set<int>& nums3)
{
    std::cout << comment
              << " nums1: " << nums1.size() << ','
              << " nums2: " << nums2.size() << ','
              << " nums3: " << nums3.size() << '\n';
}

void display(char const* comment, const std::set<int>& v)
{
    std::cout << comment << "{ ";
    for (int e : v) {
        std::cout << e << ' ';
    }
    std::cout << "}\n";
}

int main()
{
    std::set<int> nums1 {3, 1, 4, 6, 5, 9};
    std::set<int> nums2;
    std::set<int> nums3;

    display_sizes("Сначала:\n", nums1, nums2, nums3);

    // присвоение копированием копирует данные nums1 в nums2
    nums2 = nums1;

    display_sizes("После присвоения:\n", nums1, nums2, nums3);

    // присвоение перемещением перемещает данные из nums1 в nums3,
    // изменяя, как nums1, так и nums3
    nums3 = std::move(nums1);

    display_sizes("После присвоения перемещением:\n", nums1, nums2, nums3);

    display("Теперь nums3 = ", nums3);

    // Присвоение копированием списка инициализаторов копирует данные в nums3
    nums3 = {1, 2, 3};

    display("После присвоения initializer_list \n nums3 = ", nums3);
}

Вывод:

Сначала:
 nums1: 6, nums2: 0, nums3: 0
После присвоения:
 nums1: 6, nums2: 6, nums3: 0
После присвоения перемещением:
 nums1: 0, nums2: 6, nums3: 6
Now nums3 = { 1 3 4 5 6 9 }
После присвоения initializer_list
 nums3 = { 1 2 3 }

См. также

создаёт set
(public функция-элемент) [править]