Esta es una de las posibles formas en que salgo:
struct RetrieveKey
{
template <typename T>
typename T::first_type operator()(T keyValuePair) const
{
return keyValuePair.first;
}
};
map<int, int> m;
vector<int> keys;
// Retrieve all keys
transform(m.begin(), m.end(), back_inserter(keys), RetrieveKey());
// Dump all keys
copy(keys.begin(), keys.end(), ostream_iterator<int>(cout, "\n"));
Por supuesto, también podemos recuperar todos los valores del mapa al definir otro functor RetrieveValues .
¿Hay alguna otra forma de lograr esto fácilmente? (Siempre me pregunto por qué std :: map no incluye una función miembro para que lo hagamos).
c++
dictionary
stl
stdmap
Owen
fuente
fuente
keys.reserve(m.size());
.Respuestas:
Si bien su solución debería funcionar, puede ser difícil de leer dependiendo del nivel de habilidad de sus compañeros programadores. Además, aleja la funcionalidad del sitio de la llamada. Lo que puede dificultar un poco el mantenimiento.
No estoy seguro de si su objetivo es obtener las claves en un vector o imprimirlas en Cout, así que estoy haciendo ambas. Puedes probar algo como esto:
O incluso más simple, si estás usando Boost:
Personalmente, me gusta la versión BOOST_FOREACH porque se escribe menos y es muy explícita sobre lo que está haciendo.
fuente
BOOST_FOREACH
? El código que propone aquí es totalmente incorrectov.reserve(m.size())
para evitar que el vector cambie de tamaño durante la transferencia.fuente
it = ...begin(); it != ...end
. Lo mejor sería, por supuesto, std :: map con un método de teclas () que devuelve ese vector ...answered Mar 13 '12 at 22:33
, que es varios meses después de que C ++ 11 se convirtió en C ++.for(auto const & imap : mapints)
.Hay un adaptador de rango de refuerzo para este propósito:
Hay un adaptador de rango map_values similar para extraer los valores.
fuente
boost::adaptors
no está disponible hasta Boost 1.43. La versión estable actual de Debian (Squeeze) solo ofrece Boost 1.42boost/range/adaptor/map.hpp
C ++ 0x nos ha dado otra solución excelente:
fuente
La respuesta de @ DanDan, usando C ++ 11 es:
y usando C ++ 14 (como lo señaló @ ivan.ukr) podemos reemplazarlo
decltype(map_in)::value_type
porauto
.fuente
keys.reserve(map_in.size());
para la eficiencia.El SGI STL tiene una extensión llamada
select1st
. ¡Lástima que no esté en STL estándar!fuente
Su solución está bien, pero puede usar un iterador para hacerlo:
fuente
Basado en la solución @ rusty-parks, pero en c ++ 17:
fuente
std::ignore
pueda usar en enlaces estructurados de esta manera. Recibo un error de compilación. Debería ser suficiente usar una variable regular, por ejemplo,ignored
que simplemente no se usa.std::ignore
está destinado para su uso con,std::tie
pero no con enlaces estructurales. He actualizado mi código.Creo que el BOOST_FOREACH presentado anteriormente es agradable y limpio, sin embargo, también hay otra opción que usa BOOST.
Personalmente, no creo que este enfoque sea tan limpio como el enfoque BOOST_FOREACH en este caso, pero boost :: lambda puede ser realmente limpio en otros casos.
fuente
Además, si tiene Boost, use transform_iterator para evitar hacer una copia temporal de las claves.
fuente
Un poco de una toma de c ++ 11:
fuente
Puede usar el impulso versátil :: transform_iterator. Transform_iterator le permite transformar los valores iterados, por ejemplo, en nuestro caso cuando desea tratar solo con las claves, no con los valores. Ver http://www.boost.org/doc/libs/1_36_0/libs/iterator/doc/transform_iterator.html#example
fuente
Aquí hay una buena plantilla de función que usa magia C ++ 11, que funciona tanto para std :: map, std :: unordered_map:
Compruébalo aquí: http://ideone.com/lYBzpL
fuente
La mejor solución STL no sgi y no boost es extender map :: iterator de esta manera:
y luego úsalos así:
fuente
Con ejemplo de mapa atómico
fuente
Ligeramente similar a uno de los ejemplos aquí, simplificado desde la
std::map
perspectiva de uso.Usar así:
fuente
map.size()
significa duplicar el retorno del tamaño del vector. Por favor, arregle para salvar a alguien más el dolor de cabeza :(Porque no puede hacerlo mejor de lo que tú puedes hacerlo. Si la implementación de un método no será superior a la implementación de una función libre, en general no debe escribir un método; Deberías escribir una función libre.
Tampoco está claro de inmediato por qué es útil de todos modos.
fuente
empty()
porque se puede implementar comosize() == 0
.std::map<T,U>
como un contenedor de pares. En Python, undict
actúa como sus teclas cuando se repite, pero le permite decird.items()
que obtenga el comportamiento de C ++. Python también proporcionad.values()
.std::map<T,U>
sin duda podría proporcionar unakeys()
yvalues()
método que devuelve un objeto que tienebegin()
yend()
que proporcionan iteradores sobre las claves y valores.