When I should use std::map::at to retrieve map element

T M picture T M · Oct 20, 2015 · Viewed 28.2k times · Source

I have read different articles on web and questions at stackoverflow, but for me it is not clear is there any exclusive case when it is better to use std::map::at to retrieve map element.

According to definition, std::map::at

Returns a reference to the mapped value of the element identified with key k.

If k does not match the key of any element in the container, the function throws an out_of_range exception.

For me only case when it is worth to use std::map::at when you 100% sure that element with particular key exist, otherwise you should consider exception handling.

  1. Is there any case where std::map::at considered as most efficient and elegant way to do? In what cases you will recommend to use std::map::at ?
  2. Am I right that it is better to use map::find() when there is a possibility to not have element with such a key? And map::find() it is faster and more elegant approach?
if ( map.find("key") != map.end() )
{
    // found 

} else
{
    // not found
}

p.s

map::operator[] sometimes can be dangerous, because if an element doesn't exist then it will inserts it.

EDITED: links somehow related link 1 link 2 link 3 link 4 link 5 link 6

Answer

Matthieu M. picture Matthieu M. · Oct 20, 2015

Contrary to most existing answers here, note that there are actually 4 methods related to finding an element in a map (ignoring lower_bound, upper_bound and equal_range, which are less precise):

  • operator[] only exist in non-const version, as noted it will create the element if it does not exist
  • at(), introduced in C++11, returns a reference to the element if it exists and throws an exception otherwise
  • find() returns an iterator to the element if it exists or an iterator to map::end() if it does not
  • count() returns the number of such elements, in a map, this is 0 or 1

Now that the semantics are clear, let us review when to use which:

  • if you only wish to know whether an element is present in the map (or not), then use count().
  • if you wish to access the element, and it shall be in the map, then use at().
  • if you wish to access the element, and do not know whether it is in the map or not, then use find(); do not forget to check that the resulting iterator is not equal to the result of end().
  • finally, if you wish to access the element if it exists or create it (and access it) if it does not, use operator[]; if you do not wish to call the type default constructor to create it, then use either insert or emplace appropriately