Tùy thuộc vào mức quá tải mà chúng ta đang nói đến, std::unordered_map::operator[]
tương đương với [unord.map.elem]
T& operator[](const key_type& k)
{
return try_emplace(k).first->second;
}
(quá tải lấy tham chiếu giá trị chỉ di chuyển k
vào try_emplace
và giống hệt nhau)
Nếu một phần tử tồn tại dưới khóa k
trong bản đồ, sau đó try_emplace
trả về một trình vòng lặp cho phần tử đó và false
. Mặt khác, try_emplace
chèn một phần tử mới bên dưới khóa k
và trả về một trình vòng lặp cho điều đó và true
[unord.map.modifier] :
template <class... Args>
pair<iterator, bool> try_emplace(const key_type& k, Args&&... args);
Thú vị đối với chúng tôi là trường hợp chưa có yếu tố nào [unord.map.modifier] / 6 :
Mặt khác chèn một đối tượng kiểu được value_type
xây dựng vớipiecewise_construct, forward_as_tuple(k), forward_as_tuple(std::forward<Args>(args)...)
(quá tải lấy tham chiếu giá trị chỉ di chuyển k
vào forward_as_tuple
và, một lần nữa, là giống hệt nhau)
Vì value_type
là pair<const Key, T>
[unord.map.overview] / 2 , điều này cho chúng ta biết rằng phần tử bản đồ mới sẽ được xây dựng dưới dạng:
pair<const Key, T>(piecewise_construct, forward_as_tuple(k), forward_as_tuple(std::forward<Args>(args)...));
Vì args
là trống khi đến từ operator[]
, nên điều này làm cho giá trị mới của chúng ta được xây dựng như là một thành viên của pair
từ không có đối số [cặp.pair] / 14 là khởi tạo trực tiếp [class.base.init] / 7 của một giá trị loại T
sử dụng ()
với tư cách là công cụ khởi tạo để khởi động giá trị khởi tạo [dcl.init] / 17.4 . Giá trị khởi tạo của an int
là khởi tạo bằng 0 [dcl.init] / 8 . Và không khởi tạo một cách int
tự nhiên khởi tạo nó int
thành 0 [dcl.init] / 6 .
Vì vậy, có, mã của bạn được đảm bảo trả về 0