8

I'm interested in removing an element with a specific key out of a map and use this element.

Something that will look like:

itr = MyMap.pop(wantedKey);
//Now MyMap is missing the element which has the key 'wantedKey'.
//Do something with this element through 'itr'.

Is there an stl map method for doing this?

EDIT

Following carleeto's response, I want to clarify: What I need is the element being removed from the map and the program being able to use it afterwards, it could be the element itself as a pair, not necessarily an iterator.

4

8 回答 8

14

There are two options: use it in-place then remove it, or move it to a local variable, remove the entry, then use it.

// use-remove
auto i = MyMap.find(wantedKey);
if (i != MyMap.end()) {
    // use-remove
    use(i->second);
    MyMap.erase(i);

    // or

    // move-remove-use
    auto x = std::move(i->second);
    MyMap.erase(i);
    use(x);
} else {
    // Not found
}
于 2013-06-10T21:00:38.640 回答
4

Not that I know of, but you can use std::map::find to get an iterator and then call std::map::erase with said iterator as an argument when you're done.

于 2013-06-10T21:00:47.213 回答
1

From your variable naming, I think you might be confusing concepts here.

itr = MyMap.pop(wantedKey);
//Do something with this element through 'itr'.

Iterators only point to elements in containers. Therefore, if you had received an iterator through a function called pop (even if it existed), the iterator would reference not the element you popped, but probably the one after or before it, like std::vector::erase. This is because the purpose of an iterator is to iterate over the elements in a container. Therefore, if an element is not in the container, you cannot get an iterator to it. However, even if you used the iterator returned by the erase function, it would not reference you would be expecting it to.

So you can erase an element from the map, like so many have pointed out, by searching for it, getting the ierator to it and then calling erase with that iterator. but you cannot get an iterator that points to element you have erased. Hope this clears things up.

UPDATE: If all you want is to access the element and use it, then all you need to do use std::map::find to get an iterator and std::map::erase to remove the item from the map, once you have finished using the iterator. The reason is that even if you have stored a copy of the iterator for future use, once you call erase, it will be invalidated. To be able to access it after you have erased it, depending on scope, you will probably need to copy it.

Finally, what you want to do is a very common task - look up a map based on a key and perform an operation on the associated element. It's quite likely that you have a list of keys to go through. You should also look up functors, std::for_each and std::transform. I realise this is not operating on the element after you have removed it, but I thought I would add it in, seeing as how its a related operation. For example: You could move all elements that match a list of keys into another container (say, a vector, and then use the above to operate on them).

于 2013-06-10T21:08:45.923 回答
0

Probably what you want to do is

itr = MyMap.find('thing in a string');

to find the iterator and then use it,

MyMap.erase(itr)

And then erase it.

于 2013-06-10T21:02:11.000 回答
0

Pop() belongs to the stack datastructure. To access an element of a map, use the [] operator (http://www.cplusplus.com/reference/map/map/operator%5B%5D/), to remove it from the map use (http://www.cplusplus.com/reference/map/map/erase/).

于 2013-06-10T21:03:05.610 回答
0
itr = MyMap.find(wantedKey);
if(itr != MyMap.end()) {
  use( itr->second );
  MyMap.erase(itr);
}
your.uncle = bob;
于 2013-06-10T21:03:52.117 回答
0

Using C++'s std::map<T, U>::find():

map.erase(map.find(key));
于 2013-06-10T21:05:29.907 回答
0

The way I did it is below. In my case the map stores std::shared_ptr values, making the copy cheap(ish), and the object ownership transferral clear.

auto it = MyMap.find( wantedkey );
if ( it == MyMap.end() ) throw runtime_error("not found");
auto ret = it->second;          // make copy of shared_ptr
MyMap.erase(it);
return ret;

The caller gets a shared_ptr with a reference count of at least one (from the copy). Note the function must return the shared_ptr by value, etc.

于 2015-02-14T07:38:48.047 回答