2010-05-07 43 views
12

Tôi có một bản đồ các đối tượng và tôi muốn cập nhật đối tượng được ánh xạ tới một khóa hoặc tạo một đối tượng mới và chèn vào bản đồ. Bản cập nhật được thực hiện bởi một chức năng khác có con trỏ đến đối tượng (cập nhật void (MyClass * obj))Bản đồ STL - chèn hoặc cập nhật

Cách tốt nhất để "chèn hoặc cập nhật" phần tử trong bản đồ là gì?

Trả lời

16

Các operator[]      

+3

Điều này có thể mang lại mã trang nhã, nếu bạn muốn chèn đối tượng 'MyClass' mặc định và sau đó cập nhật nó. Nếu bạn cần chèn một đối tượng không mặc định, hoặc không cập nhật giá trị được chèn vào, giải pháp của Charles có lẽ tốt hơn. Cập nhật –

+1

'(my_map [key])'? Điều đó cũng có nghĩa là bạn 'cập nhật' luôn (không rõ ràng từ câu hỏi). – UncleBens

+0

Điều gì sẽ xảy ra nếu khóa không tồn tại? – Konrad

0

cái gì đó như:

map<int,MyClass*> mymap; 
map<int,MyClass*>::iterator it; 

MyClass* dummy = new MyClass(); 
mymap.insert(pair<int,MyClass*>(2,dummy)); 

it = mymap.find(2); 
update(it.second); 

đây một tài liệu tham khảo thoải mái link

+0

Nếu bạn định đi theo lộ trình đó: 'MyClass & obj = mymap [2]; (&obj); ' –

+0

Có nhưng với [] bạn nên biết rằng nếu đối tượng không tồn tại, nó tạo ra một đối tượng mới (kết quả thứ hai là một con trỏ rỗng) – RvdK

+0

Không. Nếu khóa không có, nó chèn một, Vì vậy, bạn sẽ được bảo đảm để có được một đối tượng hợp lệ miễn là có bộ nhớ cho nó.Ngay cả khi đó không phải là hành vi, nó chắc chắn sẽ không mang lại một tham chiếu không hợp lệ. –

7

Với một cái gì đó giống như đoạn mã sau:

std::map<Key, Value>::iterator i = amap.find(key); 

if (i == amap.end()) 
    amap.insert(std::make_pair(key, CreateFunction())); 
else 
    UpdateFunction(&(i->second)); 

Nếu bạn muốn đo lường điều gì đó có thể cải thiện hiệu suất, bạn có thể muốn sử dụng .lower_bound() để tìm mục nhập và sử dụng làm gợi ý để chèn vào trường hợp bạn cần chèn đối tượng mới.

std::map<Key, Value>::iterator i = amap.lower_bound(key); 

if (i == amap.end() || i->first != key) 
    amap.insert(i, std::make_pair(key, CreateFunction())); 
             // Might need to check and decrement i. 
             // Only guaranteed to be amortized constant 
             // time if insertion is immediately after 
             // the hint position. 
else 
    UpdateFunction(&(i->second)); 
+0

Tôi nghĩ rằng bạn thực sự cần phải giảm 'i' nếu nó không bằng' amap.begin() ' Và do đó obviou s câu hỏi: làm thế nào để đưa ra như là một gợi ý rằng nó nên được chèn vào trong vị trí đầu tiên? Tôi cho rằng nó hoạt động với phiên bản không có gợi ý:/ –

+0

Vâng, đó là một chút của một yêu cầu warty. Việc triển khai * có thể * làm cho nó hiệu quả nếu gợi ý ngay sau vị trí chèn. Điều này có vẻ là neater ... và đây là cách nó được sửa: http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233 –

0

operator[] đã làm, những gì bạn muốn. Xem the reference để biết chi tiết.

+0

đủ kỳ quặc, tham khảo là sai. Tham chiếu nói rằng toán tử [] tương đương với chèn, nhưng m.insert (std :: make_pair ("a", "1")); m.insert (std :: make_pair ("a", "2")); không cập nhật m. m ["a"] giữ nguyên "1". m ["a"] = "2" sẽ cập nhật m. Trong đó: map m; – DavidPhillipOster

Các vấn đề liên quan