ejemplo - iterator c++ example
¿Cómo obtengo un const_iterator usando auto? (7)
Primera pregunta: ¿es posible "forzar" a un const_iterator
usando auto? Por ejemplo:
map<int> usa;
//...init usa
auto city_it = usa.find("New York");
Solo quiero consultar, en lugar de cambiar cualquier cosa apuntada por city_it
, así que me gustaría que city_it
fuera map<int>::const_iterator
. Pero al usar auto, city_it
es el mismo que el tipo de retorno de map::find()
, que es map<int>::iterator
. ¿Cualquier sugerencia?
Desde C ++ 17 puedes usar link como este:
#include <utility>
// ...
auto city_it = std::as_const(usa).find("New York");
Esta no es una interpretación drásticamente diferente de la conversión a const
en comparación con la respuesta de @ Jollymorphic, pero creo que tener una función de utilidad de una sola línea como esta es útil:
template<class T> T const& constant(T& v){ return v; }
Lo que hace que la conversión sea mucho más atractiva a simple vista:
auto it = constant(usa).find("New York");
// other solutions for direct lengths comparision
std::map<std::string, int>::const_iterator city_it = usa.find("New York");
auto city_it = const_cast<const std::map<std::string, int>&>(usa).find("New York");
Bueno, yo diría que más grande no siempre es mejor. Por supuesto, puede elegir el nombre de la función de acuerdo con sus preferencias: as_const
o simplemente const_
son posibles alternativas.
Lo siento, pero creo que la mejor sugerencia es no usar nada auto
, ya que desea realizar una conversión de tipo (implícitamente válida). auto
está destinado a deducir el tipo exacto , que no es lo que quiere aquí.
Solo escríbelo de esta manera:
std::map<std::string, int>::const_iterator city_it = usa.find("New York");
Como señaló correctamente MooingDuck, el uso de alias de tipo puede mejorar la legibilidad y el mantenimiento de su código:
typedef std::map<std::string, int> my_map;
my_map::const_iterator city_it = usa.find("New York");
No estoy en condiciones de probar esto en este momento, pero creo que hará el truco:
auto city_it = const_cast< const map<int> & >(usa).find("New York");
Otra variación que usa auto (manteniendo tanto un mutable usa como un const usa):
map<std::string, int> usa;
//...init usa
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
Si no necesitas que el mapa sea mutable después de init, hay algunas otras opciones.
puede definir usa como const e init con una llamada de función:
const map<std::string, int> usa = init_usa();
auto city_it = usa.find("New York");
o usando una lambda para iniciar un mapa const:
const auto usa = [&]()->const map<std::string, int>
{
map<std::string, int> usa;
//...init usa
return usa;
}();
auto city_it = usa.find("New York");
Puede usar auto para "rastrear" un tipo o "deducir" un tipo: // deduce auto city_it = usa.find("New York");
// track auto city_it = std::map<int>::const_iterator( usa.find("New York"));
Además, ver es el estilo moderno de conversaciones de C ++ por Herb Sutter, que cubre la mayoría de estas deducciones tipo guía. https://youtu.be/xnqTKD8uD64
Una solución limpia es trabajar con una referencia constante al mapa que de otro modo sería modificable:
const auto &const_usa = usa;
auto city_it = const_usa.find("New York");
Esto se asegurará de que no pueda modificar const_usa
, y usará iteradores const.