Does the erase method affect other iterator?

Source: Internet
Author: User

Sometimes there is a less common requirement: deleting all projects that meet certain conditions from a map has nothing to do with the map key.

For example, a map storing the student roster has the key as the student ID (INT) and the value as the name (string). It is easy to delete the map by student ID, however, if you need to delete all the students with the "Zhang" name in the map, you can only traverse it and compare them one by one.

Using namespace STD; <br/> typedef Map <int, string> map; <br/> static bool candrop (const map: value_type & V) {<br/> return 0 = strncmp (v. second. c_str (), "Zhang", 2); <br/>}

Below is the obviousError Method

:

// Method 1 (incorrect )!! <Br/> for (MAP: iterator it = themap. Begin (); themap. End ()! = It; ++ it) {<br/> If (candrop (* It) {<br/> // error: When erase is executed, it becomes invalid immediately, unknown consequences may occur when the for loop ++ it is executed. <Br/> themap. Erase (it); <br/>}< br/>}

If the VC compiler is used, because of its extension to the erase method, the following method can be used to meet the requirements correctly:

// 2nd methods, applicable only to VC <br/> for (MAP: iterator it = themap. Begin (); themap. End ()! = It;) {<br/> If (candrop (* It) {<br/> // VC extends the erase method, make it return the next valid iterator <br/> it = themap. erase (it); <br/>}else {<br/> + + it; <br/>}< br/>}

Unfortunately, the map: erase () method in the C ++ standard does not return any value, so the above Code cannot be compiled in the compiler such as G ++. To comply with the standards, there is a safe way to copy the items that do not need to be deleted to another new container, and then exchange the content of the two containers.

// 3rd methods, applicable to any compiler, with additional overhead <br/> map TMP; // Temporary Container <br/> for (MAP: iterator it = themap. begin (); themap. end ()! = It; ++ it) {<br/> If (! Candrop (* It) {<br/> // copy the Temporary container that you do not need to delete. <br/> TMP. insert (* It); <br/>}< br/> themap. swap (TMP); // switch the interior of the two containers. In this case, themap contains the correct items.

This method of "copying items that do not need to be deleted to a temporary container" complies with the c ++ standard and is easy to understand, however, if you do not need to delete a large number of projects (or the overhead of copying map values), it is not suitable. The following is another method:

// 4th methods <br/> for (MAP: iterator it = themap. Begin (); themap. End ()! = It;) {<br/> If (candrop (* It) {<br/> // before erase, increase the iterator first, Because erase has not been called yet, therefore, the incremental iterator is valid. <br/> // then, the original iterator value is used to call erase. How can I delete the correct recommendation? <br/> themap. erase (it ++); <br/>}else {<br/> + + it; <br/>}< br/>}

In the above example, the IT ++ operation first saves the original it value and then performs auto-increment operations on it. Because erase has not been called yet, the original it value is valid, auto-increment it is also valid. Then, pass the original it value to the erase () method to delete the project correctly.

The problem now is that the erase operation of map affects the iterator of the deleted project (which makes the iterator pointing to this project invalid) and other iterator? For example, the following method is used to fulfill the requirements:

// 5th methods <br/> vector <map: iterator> itlist; <br/> // save all iterator of the project to be deleted to a temporary container <br/> for (MAP: iterator it = themap. begin (); themap. end ()! = It; ++ it) {<br/> If (candrop (* It) {<br/> itlist. push_back (it); <br/>}< br/> // traverse the Temporary container and retrieve the iterator, delete one by one <br/> for (vector <map: iterator >:: iterator it2 = itlist. begin (); itlist. end ()! = It2; ++ it2) {<br/> themap. Erase (* it2); <br/>}

From the test results, the iterator stored in the Temporary container does not expire because of the failure of other iterator.

But is this the C ++ standard? If the standard does stipulate that erase does not affect other iterator, the fourth method is obviously the best ...... Unfortunately, I did not find it for a long time. Let me know. Thank you.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.