Tôi hơi bối rối bởi ngữ nghĩa của std::map::insert
. Ý tôi là, tôi không phàn nàn - tiêu chuẩn là tiêu chuẩn và API là như vậy. Tuy nhiên,Lý do cho bản đồ std của C++ chèn ngữ nghĩa?
insert
sẽ
kiểm tra hoạt động chèn cho mỗi phần tử chèn dù yếu tố khác đã tồn tại trong container với cùng giá trị quan trọng , nếu như vậy, yếu tố này không được chèn vào và giá trị ánh xạ của nó không phải là đã thay đổi theo bất kỳ cách nào.
Và - chỉ trong phiên bản đối số đơn pair<iterator,bool> insert (const value_type& x);
thậm chí nó sẽ cho bạn biết liệu nó có chèn giá trị (mới, có thể khác) vào khóa hay không. Theo như tôi hiểu, các phiên bản trình lặp sẽ tự động bỏ qua chèn nếu khóa đã tồn tại.
Đối với tôi, điều này chỉ đơn giản là truy cập trực quan, Tôi đã dự kiến phần giá trị sẽ bị ghi đè và phần giá trị cũ sẽ bị hủy khi chèn. Rõ ràng, các nhà thiết kế của STL nghĩ khác nhau - bất cứ ai biết lý do (lịch sử) hoặc có thể đưa ra một giải thích thấu đáo về cách ngữ nghĩa hiện tại tạo ra (ý nghĩa) hơn?
By dụ:
Có một vài cách cơ bản để thực hiện chèn trong một bản đồ duy nhất-key như std::map
:
- chèn, thay thế nếu đã tồn tại
- chèn, bỏ qua nếu đã tồn tại (đây là hành vi của std :: map)
- chèn, ném lỗi nếu đã tồn tại
- chèn, UB nếu đã tồn tại
bây giờ tôi đang cố gắng để hiểu tại sao insert_or_ignore
có ý nghĩa hơn insert_or_replace
(hoặc insert_or_error
)!
Tôi nhìn vào bản sao của tôi TC++PL (tiếc là tôi chỉ có phiên bản tiếng Đức), và thú vị, Stroustrup viết trong chương 17.4.1.7 (hoạt động danh sách cho đồ): (dịch thô xin lỗi từ Đức)
(...) Thông thường, người ta không quan tâm cho dù một chìa khóa (sic!) là mới chèn hoặc đã tồn tại trước khi cuộc gọi đến
insert()
(...)
Mà, có vẻ như với tôi, sẽ chỉ đúng với đặt và không cho bản đồ, bởi vì đối với bản đồ, nó sẽ tạo ra một số khác biệt nếu giá trị được cung cấp được chèn hoặc giá trị cũ vẫn còn trong bản đồ . (Nó rõ ràng không quan trọng đối với chìa khóa, vì nó là tương đương.)
Lưu ý: Tôi biết về operator[]
và tôi biết về mục 24 của Effective STL và có đề xuất efficientAddOrUpdate
chức năng. Tôi chỉ tò mò cho một lý do thành ngữ nghĩa của insert
bởi vì cá nhân tôi thấy chúng phản trực giác.
Vâng, bạn không yêu cầu sửa đổi giá trị hiện tại, bạn đã yêu cầu chèn giá trị (mới). Tôi đồng ý rằng báo cáo thất bại nhất quán sẽ là một điều tốt. Bạn vẫn có thể dereference iterator trả về và kiểm tra xem giá trị mới hoặc giá trị cũ có hiện diện hay thậm chí sử dụng trình lặp đó để cập nhật giá trị hiện tại. –
Nếu bạn muốn thay thế/tạo, sử dụng toán tử '[]'. – BoBTFish
Dưới đây là một số mã để ["chèn mạnh"] (http://stackoverflow.com/a/8337563/596781) vào bản đồ. –