2012-06-15 18 views
18

Sabemos que si intentamos acceder a una clave inexistente de std::map con el operador [], la función insertará un nuevo elemento con esa clave.operador de mapa [] y bool como valor

tenemos: std::map<std::string, bool> map_xxx;

¿Está garantizado que después de acceder a la clave inexistente de map_xxx["nonexistent_key"], el valor del segundo argumento siempre será false?

ps. si no, ¿alguna idea de cómo tener este comportamiento?

+0

Creo que su pregunta es realmente: "¿Cuál es el valor de' bool() '?", Como se desprende del código que se muestra en [esta página] (http://en.cppreference.com/w/ cpp/container/map/operator_at). – chris

+0

posible duplicado de [¿El constructor predeterminado de std :: pair <> establece tipos básicos (int, etc) en cero?] (Http://stackoverflow.com/questions/9025792/does-the-default-constructor-of -stdpair-set-basic-types-int-etc-to-zero) – ildjarn

Respuesta

26

Sí. El valor que se insertará está garantizado como false.


En C++ 98, el mecanismo se denomina inicialización por defecto, especificado como cero de inicialización para los no-clases; eso es false para booleanos.

Desde C++ 03, el mecanismo se denomina inicialización de valor, aún se especifica como inicialización cero para no clases; y por lo tanto aún false para Booleanos. Por ejemplo, veamos qué dice C++ 14 sobre esto.

De §23.4.4.3; simplemente sustituya bool por "T".

T & operador [] (key_type const & x);

  1. Efectos: Si no hay clave equivalente a x en el mapa, inserciones value_type (x, T()) en el mapa.
  2. Requiere: key_type será CopyInseable y mapped_type será DefaultInsertable en * this.

De §8.5, digerir los párrafos de abajo hacia arriba:

Para cero inicializar un objeto o de referencia de tipo T significa:

- si T es un tipo escalar (3.9), el objeto se inicializa al valor obtenido por convirtiendo el entero literal (cero) en T;

...

Para valor inicializar un objeto de tipo T significa:

- si T es un tipo de clase (posiblemente cv-cualificado) (Cláusula 9) con ningún constructor predeterminado (12.1) o un constructor predeterminado que es proporcionado por el usuario o eliminado, entonces el objeto se inicializa por defecto;

- si T es un tipo de clase (posiblemente cv calificado) sin un constructor predeterminado proporcionado por el usuario o eliminado, entonces el objeto se inicializa en cero y se verifican las restricciones semánticas para la inicialización predeterminada, y si T tiene un constructor por defecto no trivial, el objeto está inicializado por defecto;

- si T es un tipo de matriz, cada elemento se inicializa en valor;

- de lo contrario, el objeto es cero inicializado.

...

Un objeto cuya inicializador es un conjunto vacío de paréntesis, es decir, (), será valor inicializado.

De §4.12:

A prvalue de la aritmética, la enumeración sin ámbito, puntero, o puntero a tipo de miembro se puede convertir en un prvalue de tipo bool. Un valor cero, valor de puntero nulo o valor de puntero de miembro nulo se convierte en falso; cualquier otro valor se convierte en verdadero. Para la inicialización directa (8.5), un prvalue de tipo std :: nullptr_t se puede convertir a un prvalue de tipo bool; el valor resultante es falso.

Cuestiones relacionadas