Sí. std::map
tiene una función at
miembro en C++ 11 con la siguiente especificación (23.4.4.3/9):
T& at(const key_type& x);
const T& at(const key_type& x) const;
Devuelve: Una referencia a la mapped_type correspondiente a x
en *this
.
Throws: Objeto de excepción del tipo out_of_range
si no hay ese elemento.
Complejidad: logarítmico.
Sin embargo, tenga en cuenta que esta función de miembro se ha agregado específicamente al std::map
. No es requerido por el requisito más general de contenedor asociativo. Si está escribiendo código genérico que requiere algún tipo de contenedor asociativo, no puede usar este nuevo at
. En su lugar, debe continuar utilizando find
, que es parte de la asociativo concepto contenedor, o danos tu no miembros ayudante:
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");
}
O, si usted tiene una aplicación que soporta referencias rvalue y decltype
, usted no necesita dos sobrecargas:
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");
}
(O algo parecido a eso, una cosa divertida de C++ 11 es que no hay dos compiladores tienen los mismos errores y todos parecen aceptar ligeramente diferentes subconjuntos de válida- -y no válido-código C++ 11)
Diría que todos los compiladores se están acercando a C++ 11, pero esa puede ser mi auto optimista :) –
[nitpick]. El método "at" se agregó no solo a std :: map, sino también a std :: unordered_map. Estos son los únicos dos contenedores estándar en los que realmente tiene sentido tener este método. Además, su código funcionará no solo para AssociateveContainers, sino también para UnorderedAssociateveContainers, excepto para set y unordered_set y, de nuevo, apenas tiene sentido para multimap y unordered_multimap. –
@ Konstantin: Sí, quizás 'UniqueAssociativeContainer' sería un mejor nombre para el parámetro de plantilla (' UniqueAssociativeContainerOrUniqueUnorderedAssociativeContainer' es un poco demasiado pesado: -O). El punto es que hay contenedores distintos a los contenedores de la Biblioteca Estándar de C++ que cumplen con los requisitos de los conceptos de contenedor y que deben ser intercambiables con los contenedores de la Biblioteca Estándar de C++ en código genérico. El código que se basa en el nuevo 'at' no puede hacer uso de esos otros contenedores. –