Chuyển tới nội dung chính

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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án a = a;
  6. 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.
  7. Độ 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)).

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;
}