std::vector::operator=
Материал из cppreference.com
<tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
<tbody class="t-dcl-rev t-dcl-rev-num ">
</tbody><tbody>
</tbody>
| (1) | ||
vector& operator=( const vector& other ); |
(до C++20) | |
constexpr vector& operator=( const vector& other ); |
(начиная с C++20) | |
| (2) | ||
vector& operator=( vector&& other ); |
(начиная с C++11) (до C++17) |
|
vector& operator=( vector&& other ) noexcept(/* смотрите ниже */); |
(начиная с C++17) (до C++20) |
|
constexpr vector& operator=( vector&& other ) noexcept(/* смотрите ниже */); |
(начиная с C++20) | |
| (3) | ||
vector& operator=( std::initializer_list<T> ilist ); |
(начиная с C++11) (до C++20) |
|
constexpr vector& operator=( std::initializer_list<T> ilist ); |
(начиная с C++20) | |
Заменяет содержимое контейнера
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) Линейная от размера
*this и ilist.
Исключения2)
спецификация noexcept:
noexcept(std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value || std::allocator_traits<Allocator>::is_always_equal::value) |
(начиная с C++17) |
Примечания
После присвоения перемещением (перегрузка (2)), помимо случая, когда поэлементное присвоение произошло по причине несовместимых аллокаторов, ссылки, указатели и итераторы (кроме end итератора) из other остаются корректными, но ссылаются на элементы, которые теперь находятся в *this. Текущий стандарт даёт такую гарантию согласно общему утверждению из [container.requirements.general]/12, более прямая гарантия рассматривается в [lwg-2321].
Пример
Код ниже использует operator= для того, чтобы присвоить один std::vector другому:
Запустить этот код
#include <vector>
#include <iostream>
void display_sizes(char const* comment,
const std::vector<int>& nums1,
const std::vector<int>& nums2,
const std::vector<int>& nums3)
{
std::cout << comment
<< " nums1: " << nums1.size() << ','
<< " nums2: " << nums2.size() << ','
<< " nums3: " << nums3.size() << '\n';
}
void display(char const* comment, const std::vector<int>& v)
{
std::cout << comment << "{ ";
for (int e : v) {
std::cout << e << ' ';
}
std::cout << "}\n";
}
int main()
{
std::vector<int> nums1 {3, 1, 4, 6, 5, 9};
std::vector<int> nums2;
std::vector<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 = { 3 1 4 6 5 9 }
После присвоения initializer_list
nums3 = { 1 2 3 }
См. также
создаёт vector (public функция-элемент) | |
| присваивает значения контейнеру (public функция-элемент) |