Sì. std::map
ha una funzione at
membro in C++ 11 con la seguente specifica (23.4.4.3/9):
T& at(const key_type& x);
const T& at(const key_type& x) const;
ritorni: Un riferimento mapped_type corrispondente al x
in *this
.
Quantità: Un oggetto di eccezione di tipo out_of_range
se questo elemento non è presente.
Complessità: logaritmico.
Si noti tuttavia che questa funzione membro è stata aggiunta in modo specifico a std::map
. Non è richiesto dal più generale contenitore associativo requisito. Se stai scrivendo un codice generico che richiede un tipo di contenitore associativo, non puoi utilizzare questo nuovo at
. Invece, si dovrebbe continuare a utilizzare find
, che fa parte del associativa contenitore concetto , o lascia la tua aiutante non membro:
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");
}
Oppure, se si dispone di un'implementazione che supporta i riferimenti rvalue e decltype
, non avete bisogno di due overload:
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 qualcosa di simile a quello, una cosa divertente di C++ 11 è che non esistono due compilatori hanno gli stessi bug e tutti sembrano accettare leggermente diversi sottoinsiemi di valid- -e non valido - codice C++ 11)
fonte
2011-09-09 05:05:16
Direi che tutti i compilatori stanno chiudendo in C++ 11, ma quello potrebbe essere il mio io ottimista :) –
[nitpick]. il metodo 'at' è stato aggiunto non solo a std :: map, ma anche a std :: unordered_map. Questi sono gli unici due contenitori standard per cui è sensato avere questo metodo. Anche il tuo codice funzionerà non solo per AssociateveContainers, ma anche per UnorderedAssociateveContainers, ad eccezione di set e unordered_set e, ancora, non ha senso per multimap e unordered_multimap. –
@ Konstantin: Sì, forse 'UniqueAssociativeContainer' sarebbe un nome migliore per il parametro del template (' UniqueAssociativeContainerOrUniqueUnorderedAssociativeContainer' è un po 'troppo ingombrante: -O). Il punto è che ci sono contenitori diversi dai contenitori della libreria standard C++ che soddisfano i requisiti dei concetti del contenitore e che dovrebbero essere intercambiabili con i contenitori della libreria standard C++ in codice generico. Il codice che si basa sul nuovo 'at' non può fare uso di quegli altri contenitori. –