Desechar const es incorrecto, ya que el operador [] en el mapa <> creará la entrada si no está presente con una cadena predeterminada construido. Si el mapa está realmente en almacenamiento inmutable, fallará. Esto debe ser así porque el operador [] devuelve una referencia no constante para permitir la asignación. (p.ej.m [1] = 2)
Una función libre rápido de implementar la comparación:
template<typename CONT>
bool check_equal(const CONT& m, const typename CONT::key_type& k,
const typename CONT::mapped_type& v)
{
CONT::const_iterator i(m.find(k));
if (i == m.end()) return false;
return i->second == v;
}
Voy a pensar en el azúcar y la actualización sintáctica si pienso en algo.
...
El azúcar sintáctico inmediata involucrada una función gratuita que hace un mapa <> :: find() y devuelve una clase especial que envuelve mapa <> :: const_iterator, y después se ha sobrecargado el operador = =() y operator! =() para permitir la comparación con el tipo mapeado. Así que usted puede hacer algo como:
if (nonmutating_get(m, "key") == "value") { ... }
No estoy convencido de que es mucho mejor que:
if (check_equal(m, "key", "value")) { ... }
y sin duda es mucho más complejo y lo que está sucediendo es mucho menos evidente.
El objeto del envoltorio del iterador es dejar de tener objetos de datos construidos por defecto. Si no le importa, simplemente use la respuesta "obtener".
En respuesta al comentario acerca del conseguir prefiriéndose más de una comparación con la esperanza de encontrar algún uso futuro, tengo estos comentarios:
decir lo que quiere decir: llamar a una función llamada "check_equal" deja en claro que está haciendo una comparación de igualdad sin creación de objetos.
Recomiendo solo la implementación de funcionalidad cuando lo necesite. Hacer algo antes de eso es a menudo un error.
Dependiendo de la situación, un constructor predeterminado podría tener efectos secundarios. Si está comparando, ¿por qué hacer algo extra?
El argumento SQL: NULL no es equivalente a una cadena vacía. ¿Es la ausencia de una clave de su contenedor realmente la misma que la clave que está presente en su contenedor con un valor construido por defecto?
Habiendo dicho todo esto, un objeto predeterminado construida es equivalente a usar mapa <> :: operador [] en un recipiente no const. Y tal vez tenga un requisito actual para una función get que devuelva un objeto construido por defecto; Sé que he tenido ese requisito en el pasado.
Voy por esta implementación, colocándola en una biblioteca de soporte para que no tengamos que volver a implementarla en todas partes :) Me encantaría que STL se centrara más en la buena y vieja conveniencia de la caja ... Gracias :) –
¡Eche un vistazo a la solución de janm también! ¡su función de comparación no será verdadera para una clave que no está en el mapa en combinación con una comparación predeterminada! – xtofl
BTW, la única razón por la que la función devuelve V, y no V const &, es porque si se devuelve el valor por defecto de V(), no queremos devolver una referencia colgante. Si está preparado para garantizar que el artículo exista, simplemente haga "return iter-> second;" (comportamiento indefinido si el artículo no existe). –