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

std::unordered_multimap::emplace_hint

#include <unordered_map>

template <class... Args>
iterator emplace_hint(const_iterator hint, Args&&... args);

Xây dựng (construct) một phần tử mới (cặp key-value) trực tiếp trong std::unordered_multimap, tương tự như emplace(), nhưng bạn có thể cung cấp thêm một gợi ý (hint) về vị trí chèn để có thể tối ưu hóa hiệu suất (nhưng không bắt buộc phải tối ưu).

Tham số

hint

  • const_iterator trỏ đến vị trí gợi ý để chèn phần tử mới.

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ặp key-value). Các đối số này sẽ được truyền đến constructor của std::pair<const Key, T>.

Giá trị trả về

iterator

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

Đặc điểm

  1. Xây dựng phần tử tại chỗ (In-place construction): Giống như emplace(), emplace_hint() tạo phần tử mới trực tiếp trong bộ nhớ của std::unordered_multimap, tránh việc tạo ra các đối tượng tạm thời không cần thiế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_hint() giúp tránh việc sao chép (copy) hoặc di chuyển (move) các đối tượng.
  3. Hỗ trợ variadic template: emplace_hint() 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 std::pair<const Key, T>.
  4. Gợi ý vị trí chèn (hint): Tham số hint cho phép bạn cung cấp gợi ý về vị trí chèn. Tuy nhiên, với std::unordered_multimap (không có thứ tự), gợi ý này thường không mang lại lợi ích đáng kể về hiệu suất so với emplace().
  5. Có thể làm thay đổi iterator: Việc chèn phần tử vào std::unordered_multimap có thể làm thay đổi (invalidate) các iterator đang trỏ đến các phần tử trong std::unordered_multimap do rehash.
  6. Phân biệt với emplace(): emplace_hint() tương tự emplace() nhưng có thêm tham số hint để gợi ý vị trí chèn. Với std::unordered_multimap, hint thường không mang lại hiệu quả rõ rệt.
  7. 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_hint() sẽ xây dựng phần tử tại chỗ trong std::unordered_multimap.
  8. Có thể ném ngoại lệ: Nếu việc cấp phát bộ nhớ cho phần tử mới thất bại, emplace_hint() có thể ném ra ngoại lệ std::bad_alloc. Ngoài ra, nếu constructor của std::pair<const Key, T> ném ngoại lệ, emplace_hint() cũng sẽ ném ngoại lệ.
  9. Luôn chèn: emplace_hint() của std::unordered_multimap luôn chèn phần tử mới kể cả khi key đã tồn tại.
  10. Độ phức tạp: Phụ thuộc vào độ chính xác của hint, nhưng nhìn chung là tương tự emplace():
    • Trung bình: O(1)
    • Trường hợp xấu nhất: O(n), với n là số phần tử trong std::unordered_map.

Ví dụ

#include <iostream>
#include <unordered_map>
#include <string>

int main() {
std::unordered_multimap<std::string, int> myumm;

// Chèn các phần tử, sử dụng emplace_hint() với gợi ý
// Gợi ý trong trường hợp này không có nhiều ý nghĩa với unordered_multimap
// Nhưng với các container có thứ tự, vị trí gợi ý có thể giúp tối ưu
auto it = myumm.emplace_hint(myumm.end(), "banana", 2); // Gợi ý chèn vào cuối
it = myumm.emplace_hint(it, "apple", 1); // Gợi ý chèn vào trước "banana"
it = myumm.emplace_hint(myumm.end(), "orange", 3); // Gợi ý chèn vào cuối
it = myumm.emplace_hint(it, "apple", 4); // Chèn "apple" lần nữa

std::cout << "myumm:\n";
for (const auto& p : myumm) {
std::cout << " (" << p.first << ", " << p.second << ")";
}
std::cout << '\n'; // Output: myumm: (orange, 3) (apple, 1) (apple, 4) (banana, 2) (thứ tự có thể khác)

return 0;
}

Các hàm liên quan

emplaceXây dựng (construct) một phần tử mới (cặp key-value) trực tiếp trong std::unordered_map tại vị trí thích hợp
insertChèn một phần tử mới (cặp key-value) vào std::unordered_multimap
findTìm kiếm một phần tử có key bằng với giá trị key cho trước trong std::unordered_multimap