Question

If I want to remove a single element from a map (and I don't care about the return value apart from possibly error checking), there are two ways that I could it: erase by key or erase by value:

http://ideone.com/YWocN7

#include <iostream>
#include <map>
using namespace std;

void printMap(const std::map<int, double>& m)
{
    for (auto kv : m)
    {
        std::cout << '{' << kv.first << ", " << kv.second << '}';
    }
    std::cout << '\n';
}

int main() {
    std::cout << "erase by iterator:\n";
    std::map<int, double> m1 = { { 1, 1.1 }, { 2, 2.2 }, { 3, 3.3 } };
    printMap(m1);
    m1.erase(m1.find(2));
    printMap(m1);

    std::cout << "erase by key:\n";
    std::map<int, double> m2 = { { 1, 1.1 }, { 2, 2.2 }, { 3, 3.3 } };
    printMap(m2);
    m2.erase(2);
    printMap(m2);
    return 0;
}

Output:

erase by iterator:
{1, 1.1}{2, 2.2}{3, 3.3}
{1, 1.1}{3, 3.3}
erase by key:
{1, 1.1}{2, 2.2}{3, 3.3}
{1, 1.1}{3, 3.3}

Are the two methods entirely equivalent, or is there any practical reason or situation where I might prefer one over the other?

Was it helpful?

Solution

In the scenario you describe (m1.erase(2); vs. m1.erase(m1.find(2));), the two methods are should be entirely equivalent, give or take the cost of creating and returning iterators, though this depends on your STL implementation.
The point of erase by iterator is to remove an entry from the key, when you already have an iterator because of other operations your program needed to execute on the element this iterator refers to. For instance:

void processEntry(const std::pair<int, double>& p) {
     // do something like maybe writing it to a file
}

std::map<int, double> m1 = { { 1, 1.1 }, { 2, 2.2 }, { 3, 3.3 } };

const auto it = std::find_if(m1.begin(), m1.end(), [](const std::pair<int, double>& p) {
    return p.first > 1 && p.second < 3.0;
});

if (it != m1.end()) {
    processEntry(*it);
    m1.erase(it);
}

OTHER TIPS

Map erase supports erasing elemnt(s) in different ways as below

void erase( iterator pos );
iterator erase( const_iterator pos );
void erase( iterator first, iterator last );
iterator erase( const_iterator first, const_iterator last );        
size_type erase( const key_type& key );

In you case you are using erase( iterator) and erase( const key_type) even though result of both the operation is same how the operation is executed might be different.

erase( const key_type& key ); will find the key and then erase it.

erase( iterator) already has the position which wants to erase the element

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top