std::list::splice
#include <list>
// Phiên bản 1: Chuyển toàn bộ list other
void splice(const_iterator pos, list& other);
void splice(const_iterator pos, list&& other); // (since C++11)
// Phiên bản 2: Chuyển một phần tử đơn lẻ
void splice(const_iterator pos, list& other, const_iterator it);
void splice(const_iterator pos, 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(const_iterator pos, list& other, const_iterator first, const_iterator last);
void splice(const_iterator pos, list&& other, const_iterator first, const_iterator last); // (since C++11)
Chuyển (transfer) các phần tử từ một std::list khác sang std::list hiện tại, tại một vị trí xác định.
Tham số
pos
- const_iterator trỏ đến vị trí mà tại đó các phần tử sẽ được chèn vào trước
pos
.pos
phải là một iterator hợp lệ trong std::list hiện tại.
other
- std::list khác chứa các phần tử cần chuyển.
other
có thể là chính std::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ệ trongother
.
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
- Chuyển phần tử, không sao chép:
splice()
chuyển các phần tử từ std::list nguồn sang std::list đích, không tạo ra các bản sao. Do đó, thao tác này rất hiệu quả. - other trở thành rỗng (phiên bản 1): Khi chuyển toàn bộ std::list
other
,other
sẽ trở thành rỗng sau khi gọisplice()
. - 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 std::list. Ngoại trừ iterator
pos
vẫn giữ nguyên vị trí. - 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 std::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ệ trongother
, hoặcfirst
,last
không xác định một phạm vi hợp lệ trongother
, hành vi là không xác định.
- noexcept: Phiên bản move
splice()
được đánh dấu lànoexcept
(kể từ C++11), 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ệ. - Hiệu quả:
splice()
thường được thực hiện với độ phức tạp rất tốt:- Phiên bản 1 (chuyển toàn bộ):
O(1)
. - Phiên bản 2 (chuyển một phần tử):
O(1)
. - Phiên bản 3 (chuyển một phạm vi):
O(n)
, với n là số phần tử được chuyển.
- Phiên bản 1 (chuyển toàn bộ):
Ví dụ
#include <iostream>
#include <list>
int main() {
std::list<int> list1 = {1, 2, 3};
std::list<int> list2 = {4, 5, 6};
// Phiên bản 1: Chuyển toàn bộ list2 vào đầu list1
list1.splice(list1.begin(), list2);
std::cout << "list1 after splice(list1.begin(), list2):";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after splice(list1.begin(), list2): 4 5 6 1 2 3
std::cout << '\n';
std::cout << "list2 after splice(list1.begin(), list2):";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after splice(list1.begin(), list2): (empty)
std::cout << '\n';
list2 = {7,8,9};
// Phiên bản 2: Chuyển phần tử thứ hai của list2 vào cuối list1
auto it = ++++list2.begin(); // it trỏ đến phần tử 8
list1.splice(list1.end(), list2, it);
std::cout << "list1 after splice(list1.end(), list2, it):";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after splice(list1.end(), list2, it): 4 5 6 1 2 3 8
std::cout << '\n';
std::cout << "list2 after splice(list1.end(), list2, it):";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after splice(list1.end(), list2, it): 7 9
std::cout << '\n';
// Phiên bản 3: Chuyển hai phần tử đầu của list2 vào giữa list1
list1.splice(++++list1.begin(), list2, list2.begin(), ++++list2.begin());
std::cout << "list1 after splice(++++list1.begin(), list2, list2.begin(), ++++list2.begin()):";
for (int x : list1) std::cout << ' ' << x; // Output: list1 after splice(++++list1.begin(), list2, list2.begin(), ++++list2.begin()): 4 5 7 9 6 1 2 3 8
std::cout << '\n';
std::cout << "list2 after splice(++++list1.begin(), list2, list2.begin(), ++++list2.begin()):";
for (int x : list2) std::cout << ' ' << x; // Output: list2 after splice(++++list1.begin(), list2, list2.begin(), ++++list2.begin()): (empty)
std::cout << '\n';
return 0;
}
Các hàm liên quan
insert | Chèn một hoặc nhiều phần tử mới vào một vị trí cụ thể trong std::list |
merge | Hợp nhất (merge) hai std::list đã được sắp xếp thành một std::list duy nhất |
erase | Xóa một hoặc nhiều phần tử khỏi std::list tại một vị trí cụ thể hoặc trong một phạm vi |