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

std::forward_list::emplace_after

#include <forward_list>

template <class... Args>
iterator emplace_after(const_iterator pos, Args&&... args);

Xâ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, 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à sau đó phần tử mới sẽ được chèn vào.
  • pos phải là một iterator hợp lệ trong forward_list, bao gồm cả giá trị trả về bởi before_begin() (để chèn vào đầu danh sách).

args

  • Trả về một iterator trỏ đến phần tử vừa mới được chèn vào.

Giá trị trả về

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

Đặc điểm

  1. Xây dựng phần tử tại chỗ (In-place construction): emplace_after() tạo phần tử mới trực tiếp trong bộ nhớ của forward_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.
  2. Tránh sao chép và di chuyển: Bằng cách xây dựng phần tử tại chỗ, emplace_after() 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.
  3. Hỗ trợ variadic template: emplace_after() 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ử.
  4. Có thể làm thay đổi iterator: Việc chèn phần tử vào forward_list có thể làm thay đổi (invalidate) các iterator đang trỏ đến các phần tử phía sau vị trí chèn. Iterator pos và iterator trỏ đến các phần tử trước vị trí chèn vẫn hợp lệ.
  5. Phân biệt với insert_after(): insert_after() sẽ tạo bản sao hoặc di chuyển phần tử được truyền vào trong khi đó emplace_after sẽ xây dựng phần tử tại chỗ trong forward_list, cho phép dùng emplace_after() ngay cả khi kiểu phần tử không hỗ trợ copy/move constructor.
  6. Trường hợp pos không hợp lệ: Nếu pos không hợp lệ (ví dụ: không trỏ đến forward_list hiện tại), hành vi là không xác định.
  7. Độ phức tạp: Độ phức tạp của emplace_after()O(1) - thời gian hằng số cho việc chèn một phần tử (không tính thời gian khởi tạo phần tử).

Ví dụ

#include <iostream>
#include <forward_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::forward_list<NonCopyable> mylist;

// mylist.insert_after(mylist.before_begin(), NonCopyable(10)); // Error: Copy constructor is deleted

mylist.emplace_after(mylist.before_begin(), 10); // OK: Constructs the element in-place
mylist.emplace_after(mylist.begin(), 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_frontXây dựng một phần tử mới trực tiếp tại đầu forward_list
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
splice_afterChuyể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
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
assignGán các phần tử mới cho forward_list, thay thế nội dung hiện tại của nó