2011-12-23 29 views
9

Tôi đã lên và xuống stackoverflow và thậm chí rất, rất đẹp Dr. Dobbs article nhưng tôi không thể tìm thấy một câu trả lời dứt khoát cho câu hỏi.Làm cách nào để xóa * VÀ TIẾP TỤC * bằng cách sử dụng std :: reverse_iterator?

Một phần câu trả lời cho câu hỏi What are the shortcomings of std::reverse_iterator? nói rằng hoàn toàn không thể.


std::list::reverse_iterator it = list.rbegin(); 

while( it != list.rend()) 
{ 
    int value=*it; 
    if(some_cond_met_on(value)) 
    {  
     ++it; 
     list.erase(it.base()); 
    } 
    else 
    { 
    ++it; 
    } 
} 

PS: Tôi biết có các lựa chọn thay thế khác, chẳng hạn như erase_if(), nhưng tôi đang tìm câu trả lời cho câu hỏi cụ thể này.

Trả lời

15

Nó chỉ nên

std::list<int>::reverse_iterator it = list.rbegin(); 

while( it != list.rend()) 
{ 
    int value=*it; 
    if(some_cond_met_on(value)) 
    {  
     ++it; 
     it= reverse_iterator(list.erase(it.base()); // change to this! 
    } 
    else 
    { 
    ++it; 
    } 
} 
+0

tôi sẽ cung cấp cho nó một thử . Làm thế nào bạn tìm ra cái này? (Chỉ cần hỏi để tìm hiểu cách học) – Migs

+0

@Migs, bất biến của trình lặp ngược là: '& * (reverse_iterator (i)) == & * (i - 1)'. Bản đồ ngược từ đó (hoặc chỉ nghĩ về việc xóa 'rbegin()') và bạn nhận được mã trong câu trả lời. – MSN

+0

Cảm ơn @MSN. Nó hoạt động hoàn hảo. Tôi đọc điều bất biến đó trong bài viết của Dobbs, nhưng tôi đoán tôi không thể hiểu được những tác động của nó. Tôi sẽ tiếp tục nhìn chằm chằm cho đến khi có điều gì đó (hy vọng) xảy ra. – Migs

0

Hầu hết erase() hiện thực tôi đã thấy trả lại lặp tiếp theo trong chuỗi cho chính xác tình huống này, ví dụ:

std::list<int>::reverse_iterator it = list.rbegin(); 
while(it != list.rend()) 
{ 
    int value = *it; 
    if(some_cond_met_on(value)) 
    { 
     it = list.erase(it); 
    } 
    else 
    { 
     ++it; 
    } 
} 
+0

Điều này là chính xác. Tuy nhiên, xóa là một thành viên của cấu trúc, không phải là trình lặp. Như vậy, cho dù bạn đang sử dụng một trình lặp hoặc trình đảo ngược, thì xóa() vẫn chấp nhận và trả về một trình lặp. Không có r_erase(), nó chấp nhận và trả về một reverse_iterator. –

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