2010-06-16 3 views

Trả lời

6

Bạn không cần một vòng lặp như bạn đang đối phó với một bộ.

std::set<Color>::iterator it = myColorContainer.find(Yellow); 
if (it != it.myColorContainer.end()){ 
    DoSomeProcessing(*it); 
    myColorContainer.erase(it); 
} 
+1

là tiêu chuẩn tuân thủ. Tôi đồng ý @Viktor Sehr điều này sẽ là cách ưa thích để loại bỏ một yếu tố từ bộ này. Tuy nhiên, câu hỏi đặt ra cách yêu cầu đoạn mã hoạt động. –

+0

@daramarak: Tôi nghĩ bạn đã trả lời trong khi tôi chỉnh sửa mã (nghĩ rằng đó là một std :: vector trong bài đăng đầu tiên của tôi) –

7

Hãy thử:

for(std::set<Color>::iterator it = myColorContainer.begin(); 
    it != myColorContainer.end();) { // note missing it++ 
    if((*it) == Yellow) { 
     DoSomeProcessing(*it); 
     myColorContainer.erase(it++); // post increment (original sent to erase) 
    } 
    else { 
     ++it; // more efficient than it++; 
    } 
} 
+0

Điều này cũng không hoạt động. Bạn nên gán giá trị trả về của xóa cho nó một lần nữa. – Patrick

+0

Trình lặp lại được trả về là một triển khai cụ thể của microsoft mà phá vỡ tiêu chuẩn: http://msdn.microsoft.com/en-us/library/8h4a3515%28VS.80%29.aspx. Chắc chắn, bạn cần phải tăng iterator sau khi xóa. –

+1

Sự sollution này là hoàn hảo nếu bạn không thể sử dụng m $ -specific thực hiện và cần phải sử dụng một vòng lặp. Nếu bạn không cần sử dụng vòng lặp, tùy chọn của Viktor thậm chí còn tốt hơn. Cảm ơn câu trả lời tuyệt vời. Bạn đã giúp đỡ rất nhiều. Mã số – scippie

2
for (std::set<Color>::iterator i = myColorContainer.begin(); 
      i!=myColorContainer.end(); /* No i++ */) 
{ 
    if (*i == Yellow) 
    { 
     DoSomeProccessing(*i); 
     std::set<Color>::iterator tmp = i; 
     ++i; 
     myColorContainer.erase(tmp); 
    } 
    else { 
     ++i; 
    } 
} 

Khi bạn đi đến thông điệp tiếp theo với ++i nó được đảm bảo để có giá trị - tài sản của std::set đó lặp trên các yếu tố chèn không bao giờ chấm dứt hiệu lực trừ khi các yếu tố được lấy ra.

Vì vậy, bây giờ bạn có thể xóa an toàn mục nhập trước đó.