I was trying to figure out how to return a value from a map in a const method and I stumbled on the at() method for map in gcc 4.6.
When I looked this up I realized it was non-standard:
C++ map access discards qualifiers (const)
But it sure is a whole lot less verbose than the find() approach. I was wondering if the C++11 has rectified this - is at() for map part of the new standard?
Yes. std::map
has an at
member function in C++11 with the following specification (23.4.4.3/9):
T& at(const key_type& x); const T& at(const key_type& x) const;
Returns: A reference to the mapped_type corresponding to
x
in*this
.Throws: An exception object of type
out_of_range
if no such element is present.Complexity: logarithmic.
Note however that this member function has been added specifically to std::map
. It is not required by the more general associative container requirement. If you are writing generic code that requires some associative container type, you can't use this new at
. Instead, you should continue to use find
, which is part of the associative container concept, or write your own non-member helper:
template <typename AssociativeContainer>
typename AssociativeContainer::mapped_type&
get_mapped_value(AssociativeContainer& container,
typename AssociativeContainer::key_type const& key)
{
typename AssociativeContainer::iterator it(container.find(key));
return it != container.end() ? it->second : throw std::out_of_range("key");
}
template <typename AssociativeContainer>
typename AssociativeContainer::mapped_type const&
get_mapped_value(AssociativeContainer const& container,
typename AssociativeContainer::key_type const& key)
{
typename AssociativeContainer::const_iterator it(container.find(key));
return it != container.end() ? it->second : throw std::out_of_range("key");
}
Or, if you have an implementation that supports rvalue references and decltype
, you don't need two overloads:
template <typename AssociativeContainer, typename Key>
auto get_mapped_value(AssociativeContainer&& container, Key const& key)
-> decltype(std::declval<AssociativeContainer>().begin()->second)&
{
auto const it(container.find(key));
return it != container.end() ? it->second : throw std::out_of_range("key");
}
(Or something close to that; one fun thing about C++11 is that no two compilers have the same bugs and all seem to accept slightly different subsets of valid--and invalid--C++11 code.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With