2010-07-26 39 views
5

Đây là phần tiếp theo của câu hỏi trước tôi có (Complexity of STL max_element).xóa phần tử tối đa từ bộ STL

Tôi muốn cơ bản bật phần tử tối đa từ tập hợp, nhưng tôi đang gặp sự cố.

Đây là khoảng mã của tôi:

set<Object> objectSet; 

Object pop_max_element() { 
    Object obj = *objectSet.rbegin(); 
    set<Object>::iterator i = objectSet.end()--; //this seems terrible 
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer 
    return obj; 
} 

Trước đó tôi đã cố gắng objectSet.erase(objectSet.rbegin()); nhưng trình biên dịch phàn nàn rằng không có chức năng phù hợp (tôi đoán nó không thích reverse_iterator). Tôi biết không có kiểm tra cho một bộ trống, nhưng nó không khi objectSet.size() >> 0.

+0

'* objectSet.rbegin();' là lỗi đánh máy? bạn đang dereferencing bộ? –

+1

Không, đó là trình lặp được bỏ qua. Dấu chấm gắn chặt hơn ngôi sao. –

Trả lời

9

Bạn đang khá gần, nhưng bạn đang cố gắng làm một chút quá nhiều trong việc chuyển giao iterator đó. Bạn đang áp dụng nhà cung cấp dịch vụ sau giảm giá cho bất kỳ khoản thanh toán nào end trả lại. Tôi không thực sự chắc chắn những gì mà không, nhưng nó gần như chắc chắn không phải những gì bạn muốn. Gán kết quả của end đến irồi giảm giá trị này để lấy phần tử cuối cùng của tập hợp.

set<Object>::iterator i = objectSet.end(); 
--i; 
Object obj = *i; 
objectSet.erase(i); 
return obj; 
5

Bạn cần phải làm điều này:

set<Object> objectSet; 

Object pop_max_element() { 
    Object obj = *objectSet.rbegin(); 
    set<Object>::iterator i = --objectSet.end(); // NOTE: Predecrement; not postdecrement. 
    objectSet.erase(i); //*** glibc detected *** free(): invalid pointer 
    return obj; 
} 
5

Tuyên bố

set<Object>::iterator i = objectSet.end()--; 

phương tiện 'cuối assign() để tôi sau đó giảm một biến tạm thời mà là về để được vứt bỏ' . Nói cách khác, nó giống như set<Object>::iterator i = objectSet.end(); và tôi chắc chắn bạn nhận ra rằng bạn không thể xóa kết thúc(), vì nó trỏ đến một kết thúc. Sử dụng một cái gì đó như thế này thay thế:

assert(!objectSet.empty()); // check there is something before end 
set<Object>::iterator i = objectSet.end(); 
--i; 
objectSet.erase(i); 

và đó là okay, đó là một cách hợp pháp để tái sản xuất .back() cho một bộ.

Ngoài ra, trình lặp ngược lại có thành viên base() để chuyển đổi sang trình lặp bình thường và tôi đoán bạn chỉ có thể xóa các trình vòng lặp bình thường - hãy thử objectSet.erase(objectSet.rbegin().base()).

+0

Tôi đã thử rbegin(). Base(), không có kết quả. – sas4740

+3

'rbegin(). Base()' giống với 'end()'. –

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