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

std::map::emplace

#include <map>

template <class... Args>
pair<iterator, bool> emplace(Args&&... args);

Xây dựng (construct) một phần tử mới (cặp key-value) trực tiếp trong std::map tại vị trí thích hợp (dựa trên key), tránh việc sao chép hoặc di chuyển không cần thiết.

Tham số

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ề

std::pair<iterator, bool>

  • iterator: Một iterator trỏ đến phần tử vừa được chèn (nếu chèn thành công) hoặc phần tử đã tồn tại có key tương đương (nếu chèn thất bại).
  • bool: true nếu phần tử được chèn thành công (key mới), false nếu phần tử đã tồn tại với key đó (chèn thất bại).

Đặc điểm

  1. 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::map 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() 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() 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. Có thể làm thay đổi iterator: Việc chèn phần tử vào std::map có thể làm thay đổi (invalidate) các iterator đang trỏ đến các phần tử trong std::map.
  5. 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::map, cho phép dùng emplace() ngay cả khi kiểu phần tử không hỗ trợ copy/move constructor.
  6. 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() 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() cũng sẽ ném ngoại lệ.
  7. Chèn phần tử duy nhất theo key: std::map chỉ lưu trữ các phần tử có key duy nhất. Nếu bạn cố gắng chèn một phần tử có key đã tồn tại, emplace() sẽ không chèn thêm phần tử mới và second của pair trả về sẽ là false.
  8. Độ phức tạp: Độ phức tạp của emplace()O(log n), với n là số phần tử trong std::map.

Ví dụ

#include <iostream>
#include <map>
#include <string>

int main() {
std::map<std::string, int> mymap;

// Chèn một phần tử mới vào map, sử dụng emplace()
auto ret = mymap.emplace("apple", 1);

// Kiểm tra xem phần tử đã được chèn thành công hay chưa
if (ret.second) {
std::cout << "Element (\"apple\", 1) inserted successfully.\n";
std::cout << "Iterator points to: (" << ret.first->first << ", " << ret.first->second << ")\n";
}

// Chèn thêm các phần tử khác
mymap.emplace("banana", 2);
mymap.emplace("orange", 3);

// Thử chèn một phần tử có key đã tồn tại
auto ret2 = mymap.emplace("apple", 10); // Chèn thất bại vì key "apple" đã tồn tại
if (!ret2.second) {
std::cout << "Insertion of (\"apple\", 10) failed (key already exists).\n";
std::cout << "Existing value for apple: " << ret2.first->second << std::endl;
}

// In ra các phần tử trong map
std::cout << "mymap:\n";
for (const auto& p : mymap) {
std::cout << " (" << p.first << ", " << p.second << ")";
}
std::cout << '\n';
// Output:
// mymap:
// (apple, 1) (banana, 2) (orange, 3)

return 0;
}

Các hàm liên quan

emplace_hintXây dựng (construct) một phần tử mới (cặp key-value) trực tiếp trong std::map với một gợi ý (hint)
insertChèn một phần tử mới (cặp key-value) vào std::map
eraseXóa một hoặc nhiều phần tử khỏi std::map