std::list::operator=
#include <list>
// 1. Copy assignment operator
list& operator=(const list& other);
// 2. Move assignment operator (C++11)
list& operator=(list&& other) noexcept;
// 3. Initializer list assignment operator (C++11)
list& operator=(initializer_list<value_type> ilist);
Gán nội dung của một std::list khác hoặc một danh sách khởi tạo cho std::list hiện tại.
Tham số
other
- std::list nguồn cần gán.
ilist
- Danh sách khởi tạo chứa các phần tử cần gán.
Giá trị trả về
list&
: Tham chiếu đến std::list hiện tại (sau khi đã gán).
Đặc điểm
- Thay thế nội dung: Các toán tử gán thay thế toàn bộ nội dung hiện tại của std::list bằng nội dung mới.
- Copy vs. Move:
- Copy assignment tạo một bản sao độc lập của std::list nguồn.
- Move assignment di chuyển tài nguyên (dữ liệu) từ std::list nguồn sang std::list đích, làm cho std::list nguồn trở thành rỗng, hiệu quả hơn sao chép.
- Initializer list: Phiên bản gán từ danh sách khởi tạo cung cấp cách thức tiện lợi để gán các giá trị cố định cho std::list.
- noexcept: Move assignment operator được đánh dấu là
noexcept
, nghĩa là nó được đảm bảo không ném ra ngoại lệ nào. - Tự gán (self-assignment): Toán tử
operator=
được cài đặt để tự phát hiện và xử lý đúng các trường hợp tự gána = a;
- An toàn exception: Trong trường hợp copy assignment, nếu exception xảy ra (ví dụ: std::bad_alloc khi cấp phát bộ nhớ cho các phần tử mới, hoặc exception từ copy constructor của
value_type
), list đích sẽ không thay đổi. Đối với move assignment, list nguồn sẽ empty. - Độ phức tạp:
- Copy assignment: Độ phức tạp tuyến tính theo kích thước của std::list nguồn (
O(n)
). - Move assignment: Độ phức tạp thường là hằng số (
O(1)
). - Initializer list assignment: Độ phức tạp tuyến tính theo kích thước của danh sách khởi tạo (
O(n)
).
- Copy assignment: Độ phức tạp tuyến tính theo kích thước của std::list nguồn (
Ví dụ
#include <iostream>
#include <list>
int main() {
std::list<int> list1 = {1, 2, 3};
std::list<int> list2 = {4, 5};
std::list<int> list3;
// 1. Copy assignment
list3 = list1;
std::cout << "list3 after copy assignment from list1:";
for (int x : list3) std::cout << ' ' << x; // Output: list3 after copy assignment from list1: 1 2 3
std::cout << '\n';
// 2. Move assignment
list3 = std::move(list2);
std::cout << "list3 after move assignment from list2:";
for (int x : list3) std::cout << ' ' << x; // Output: list3 after move assignment from list2: 4 5
std::cout << '\n';
std::cout << "list2 after move assignment:";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after move assignment: (empty)
std::cout << '\n';
// 3. Initializer list assignment
list3 = {7, 8, 9, 10};
std::cout << "list3 after initializer list assignment:";
for (int x : list3) std::cout << ' ' << x; // Output: list3 after initializer list assignment: 7 8 9 10
std::cout << '\n';
return 0;
}