Professional C__ - Marc Gregoire [245]
// Use adjacent_find() to find instances of two or more identical names
// next to each other.
// Loop until adjacent_find() returns the end iterator.
set for (auto lit = allNames.cbegin(); lit != allNames.cend(); ++lit) { lit = adjacent_find(lit, allNames.cend()); if (lit == allNames.cend()) { break; } duplicates.insert(*lit); } return duplicates; } Code snippet from AuditVoterRolls\AuditVoterRolls.cpp In this implementation, allNames is of type list set { set set for (auto& district : votersByDistrict) { for (auto& name : district.second) { if (!allNames.insert(name).second) duplicates.insert(name); } } return duplicates; } Code snippet from AuditVoterRolls\AuditVoterRolls.cpp Testing the auditVoterRolls Function That’s the complete implementation of the voter roll audit functionality. Here is a small test program: // Initialize map using uniform initialization VotersMap voters = { {"Orange", {"Amy Aardvark", "Bob Buffalo", "Charles Cat", "Dwayne Dog"}}, {"Los Angeles", {"Elizabeth Elephant", "Fred Flamingo", "Amy Aardvark"}}, {"San Diego", {"George Goose", "Heidi Hen", "Fred Flamingo"}} }; list // Local lambda expression to print a district auto printDistrict = [](const DistrictPair& district) { cout << district.first << ":"; for (auto& str : district.second) cout << " {" << str << "}"; cout << endl; }; cout << "Before Audit:" << endl; for_each(voters.cbegin(), voters.cend(), printDistrict); cout << endl; auditVoterRolls(voters, felons); cout << "After Audit:" << endl; for_each(voters.cbegin(), voters.cend(), printDistrict); cout << endl; Code snippet from AuditVoterRolls\AuditVoterRolls.cpp The output of the program is: Before Audit: Los Angeles: {Elizabeth Elephant} {Fred Flamingo} {Amy Aardvark} Orange: {Amy Aardvark} {Bob Buffalo} {Charles Cat} {Dwayne Dog} San Diego: {George Goose} {Heidi Hen} {Fred Flamingo} After Audit: Los Angeles: {Elizabeth Elephant} Orange: {Dwayne Dog} San Diego: {George Goose} {Heidi Hen} SUMMARY If you aren’t impressed by the algorithms and function objects, or find them too complex, you obviously don’t have to use them. Feel free to pick and choose as well: If the find() algorithm fits perfectly in your program, don’t eschew it just because you aren’t using the other algorithms. Also, don’t take the STL as an all-or-nothing proposition. If you want to use only the vector container and nothing else, that’s fine too. The next chapters discuss a couple of other aspects of the C++ Standard Library. Chapter 14 discusses strings in C++, while Chapter 15 explains the concept of streams for input and output (I/O). Chapter 16 covers a number of
This chapter concludes the basic STL functionality. It provided an overview of the various algorithms and function objects available for your use. It also showed you how to use the new C++11 lambda expressions, which make it often easier to understand what your code is doing. We hope that you have gained an appreciation for the usefulness of the STL containers, algorithms, and function objects. If not, think for a moment about rewriting the voter registration audit example without the STL. You would need to write your own linked-list and map classes, and your own searching, removing, iterating, and other algorithms. The program would be much longer, harder to debug, and more difficult to maintain.