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

std::forward_list::splice_after

#include <forward_list>

// Phiên bản 1: Chuyển toàn bộ forward_list other
void splice_after(const_iterator pos, forward_list& other);
void splice_after(const_iterator pos, forward_list&& other); // (since C++11)

// Phiên bản 2: Chuyển một phần tử đơn lẻ
void splice_after(const_iterator pos, forward_list& other, const_iterator it);
void splice_after(const_iterator pos, forward_list&& other, const_iterator it); // (since C++11)

// Phiên bản 3: Chuyển một phạm vi các phần tử
void splice_after(const_iterator pos, forward_list& other, const_iterator first, const_iterator last);
void splice_after(const_iterator pos, forward_list&& other, const_iterator first, const_iterator last); // (since C++11)

Chuyển (transfer) các phần tử từ một forward_list khác hoặc từ một phạm vi trong forward_list khác sang forward_list hiện tại, sau một vị trí iterator đã cho. Đây là một thao tác nối (splice) danh sách.

Tham số

pos

  • const_iterator trỏ đến vị trí mà sau đó các phần tử sẽ được chèn vào.
  • pos phải là một iterator hợp lệ trong forward_list hiện tại, bao gồm cả giá trị trả về bởi before_begin() (để chèn vào đầu danh sách).

other

  • forward_list khác chứa các phần tử cần chuyển. other có thể là chính forward_list hiện tại (trong trường hợp phiên bản 2 và 3).

it

  • const_iterator trỏ đến phần tử duy nhất cần chuyển từ other (phiên bản 2).
  • it phải là một iterator hợp lệ trong other.

first, last

  • const_iterator xác định phạm vi các phần tử cần chuyển từ other (phiên bản 3).
  • first phải trỏ đến phần tử đầu tiên cần chuyển, last trỏ đến phần tử sau phần tử cuối cùng cần chuyển (past-the-end).

Giá trị trả về

Không có giá trị trả về

Đặc điểm

  1. Chuyển phần tử, không sao chép: splice_after() chuyển các phần tử từ forward_list nguồn sang forward_list đích, không tạo ra các bản sao. Do đó, thao tác này rất hiệu quả.
  2. other trở thành rỗng (phiên bản 1): Khi chuyển toàn bộ forward_list other, other sẽ trở thành rỗng sau khi gọi splice_after().
  3. Có thể làm thay đổi iterator: Việc chuyển các phần tử có thể làm thay đổi (invalidate) các iterator đang trỏ đến các phần tử trong cả hai forward_list.
  4. Trường hợp đặc biệt:
    • pos không được trỏ đến các phần tử trong phạm vi [first, last) trong phiên bản 3.
    • other không được phép bằng với forward_list hiện tại trong phiên bản 1.
    • Nếu pos không hợp lệ, it không hợp lệ trong other, hoặc first, last không xác định một phạm vi hợp lệ trong other, hành vi là không xác định.
  5. noexcept: Phiên bản move splice_after() được đánh dấu là noexcept, nghĩa là nó được đảm bảo không ném ra ngoại lệ nào. Các phiên bản copy thì có thể ném ngoại lệ nếu constructor, copy constructor hoặc destructor của phần tử được chèn ném ngoại lệ.

Ví dụ

#include <iostream>
#include <forward_list>

int main() {
std::forward_list<int> list1 = {1, 2, 3};
std::forward_list<int> list2 = {4, 5, 6};

// Phiên bản 1: Chuyển toàn bộ list2 vào sau phần tử đầu tiên của list1
list1.splice_after(list1.begin(), list2);
std::cout << "list1 after splice_after(list1.begin(), list2):";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after splice_after(list1.begin(), list2): 1 4 5 6 2 3
std::cout << '\n';
std::cout << "list2 after splice_after(list1.begin(), list2):";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after splice_after(list1.begin(), list2): (empty)
std::cout << '\n';

list2 = {7,8,9};
// Phiên bản 2: Chuyển phần tử đầu tiên của list2 vào đầu list1
list1.splice_after(list1.before_begin(), list2, list2.before_begin());
std::cout << "list1 after splice_after(list1.before_begin(), list2, list2.before_begin()):";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after splice_after(list1.before_begin(), list2, list2.before_begin()): 7 1 4 5 6 2 3
std::cout << '\n';
std::cout << "list2 after splice_after(list1.before_begin(), list2, list2.before_begin()):";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after splice_after(list1.before_begin(), list2, list2.before_begin()): 8 9
std::cout << '\n';

// Phiên bản 3: Chuyển hai phần tử cuối của list2 vào sau phần tử thứ hai của list1
list1.splice_after(++++list1.begin(), list2, list2.begin(), list2.end());
std::cout << "list1 after splice_after(++++list1.begin(), list2, list2.begin(), list2.end()):";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after splice_after(++++list1.begin(), list2, list2.begin(), list2.end()): 7 1 4 8 9 5 6 2 3
std::cout << '\n';
std::cout << "list2 after splice_after(++++list1.begin(), list2, list2.begin(), list2.end()):";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after splice_after(++++list1.begin(), list2, list2.begin(), list2.end()): (empty)
std::cout << '\n';
return 0;
}

Các hàm liên quan

mergeHợp nhất (merge) hai forward_list đã được sắp xếp thành một forward_list duy nhất
swapHoán đổi nội dung của hai forward_list với nhau
insert_afterChèn một hoặc nhiều phần tử mới vào sau một vị trí iterator cho trước trong forward_list
erase_afterXóa một hoặc nhiều phần tử khỏi forward_list tại vị trí sau một iterator cho trước
emplace_afterXây dựng một phần tử mới trực tiếp vào vị trí sau một iterator cho trước trong forward_list
resizeThay đổi kích thước của forward_list