std::list::emplace
#include <list>
template <class... Args>
iterator emplace(const_iterator pos, Args&&... args);
Xây dựng (construct) một phần tử mới trực tiếp tại một vị trí được chỉ định trong std::list, tránh việc sao chép hoặc di chuyển không cần thiết.
Tham số
pos
- const_iterator trỏ đến vị trí mà tại đó phần tử mới sẽ được chèn vào. Phần tử mới sẽ được chèn trước
pos
.pos
phải là một iterator hợp lệ trong std::list.
args
- Danh sách các đối số (có thể trống) được sử dụng để khởi tạo phần tử mới. Các đối số này sẽ được truyền đến constructor của kiểu phần tử
value_type
của std::list.
Giá trị trả về
- Trả về một iterator trỏ đến phần tử vừa mới được chèn vào.
Đặc điểm
- Xây dựng phần tử tại chỗ (In-place construction):
emplace()
tạo phần tử mới trực tiếp trong bộ nhớ của std::list tại vị trí cần chèn, tránh việc tạo ra các đối tượng tạm thời không cần thiết, tối ưu hiệu suất. - Tránh sao chép và di chuyển: Bằng cách xây dựng phần tử tại chỗ,
emplace()
giúp tránh việc sao chép (copy) hoặc di chuyển (move) các đối tượng, đặc biệt hiệu quả khi làm việc với các đối tượng lớn hoặc phức tạp. - Hỗ trợ variadic template:
emplace()
sử dụng variadic template (Args&&... args), cho phép nó nhận số lượng đối số tùy ý, phù hợp với constructor của kiểu phần tử. - Có thể làm thay đổi iterator: Việc chèn phần tử vào std::list có thể làm thay đổi (invalidate) các iterator đang trỏ đến các phần tử khác trong std::list ngoại trừ iterator pos (iterator
pos
sẽ trỏ đến phần tử trước phần tử mới được chèn). - Phân biệt với
insert()
:insert()
sẽ tạo bản sao hoặc di chuyển phần tử được truyền vào trong khi đóemplace()
sẽ xây dựng phần tử tại chỗ trong std::list, cho phép dùngemplace()
ngay cả khi kiểu phần tử không hỗ trợ copy/move constructor. - Trường hợp pos không hợp lệ: Nếu
pos
không hợp lệ (ví dụ: không trỏ đến std::list hiện tại), hành vi là không xác định. - Độ phức tạp: Độ phức tạp của
emplace()
làO(1)
- thời gian hằng số (không tính thời gian khởi tạo phần tử).
Ví dụ
#include <iostream>
#include <list>
#include <string>
int main() {
std::list<std::pair<int, std::string>> mylist;
// Chèn một phần tử mới vào đầu list, sử dụng emplace()
auto it = mylist.emplace(mylist.begin(), 10, "Hello");
// Chèn một phần tử mới vào sau phần tử vừa chèn, sử dụng emplace()
mylist.emplace(it, 20, "World");
// it vẫn trỏ đến phần tử (10, "Hello")
// do emplace() chèn vào trước iterator
// Chèn một phần tử mới vào cuối list, sử dụng emplace()
mylist.emplace(mylist.end(), 30, "!");
// In ra các phần tử trong list
std::cout << "mylist:";
for (const auto& p : mylist) {
std::cout << " (" << p.first << ", " << p.second << ")";
}
std::cout << '\n'; // Output: mylist: (20, World) (10, Hello) (30, !)
return 0;
}
Với class không hỗ trợ copy/move constructor
#include <iostream>
#include <list>
class NonCopyable {
public:
NonCopyable(int val) : data(val) {}
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
// Move constructor/assignment are not necessary but good practice
NonCopyable(NonCopyable&&) = default;
NonCopyable& operator=(NonCopyable&&) = default;
int data;
};
int main() {
std::list<NonCopyable> mylist;
// mylist.insert(mylist.begin(), NonCopyable(10)); // Error: Copy constructor is deleted
mylist.emplace(mylist.begin(), 10); // OK: Constructs the element in-place
mylist.emplace(mylist.end(), 20); // OK: Constructs the element in-place
std::cout << "mylist:";
for (const auto& obj : mylist) {
std::cout << " " << obj.data;
}
std::cout << '\n'; // Output: mylist: 10 20
return 0;
}
Các hàm liên quan
emplace_front | Xây dựng (construct) một phần tử mới trực tiếp tại đầu std::list |
emplace_back | Xây dựng (construct) một phần tử mới trực tiếp tại cuối std::list |
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 |
splice | 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 |
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 |
assign | Gán các phần tử mới cho std::list, thay thế nội dung hiện tại của nó |