c++ - smart - std:: mapea el valor por defecto para el tipo incorporado
solidity español (4)
El estándar de C ++ 11 aún requiere que std :: map zero-inicialice los tipos integrados (como lo hizo el estándar anterior), pero las razones son un poco diferentes a las de la respuesta de Luke Halliwell. En particular, para ''inicializar por defecto'' un tipo de datos incorporado no significa cero inicialización en el estándar C ++ 11, sino que significa ''no hacer nada''. Lo que realmente sucede en std::map::operator[]
es una ''inicialización de valores''.
Sin embargo, el resultado final en el nuevo estándar es el mismo que en la respuesta de Luke. Los valores serán inicializados en cero. Aquí están las partes relevantes de la norma:
La sección 23.4.4.3 "acceso al elemento del mapa" dice
T & operator [] (const key_type & x);
Efectos: si no hay una clave equivalente a x en el mapa, inserta
value_type(x, T())
en el mapa....
La expresión T()
se describe en la sección 8.5.
Un objeto cuyo inicializador es un conjunto vacío de paréntesis, es decir, (), se inicializará con valores .
X a();
Y este tipo de ''inicialización de valores'' se describe en la misma sección
Para inicializar con valor un objeto de tipo T significa:
- si T es una clase de clase (posiblemente calificada para cv) (Cláusula 9) con un constructor provisto por el usuario (12.1), entonces se llama al constructor predeterminado para T (y la inicialización no es correcta si T no tiene un constructor por defecto accesible) ;
- si T es un tipo de clase no unificada (posiblemente cv calificado) sin un constructor provisto por el usuario, entonces el objeto tiene inicialización cero y, si el constructor predeterminado declarado implícitamente por T no es trivial, se llama a ese constructor.
- si T es un tipo de matriz, entonces cada elemento tiene un valor inicializado;
- de lo contrario, el objeto es cero inicializado.
Recientemente, me confundió la función std :: map operator []. En la biblioteca de MSDN, dice: "Si no se encuentra el valor clave de argumento, se inserta junto con el valor predeterminado del tipo de datos". Intenté buscar una explicación mucho más exacta para este problema. Por ejemplo, aquí: std :: map default value En esta página, Michael Anderson dijo que "el valor predeterminado lo construye el constructor predeterminado (constructor de parámetro cero)".
Ahora mi búsqueda llega a esto: "¿cuál es el valor predeterminado para el tipo incorporado?". ¿Estaba relacionado con el compilador? ¿O existe un estándar para este problema por parte del comité de stardard de c ++?
Hice una prueba en Visual Studio 2008 para el tipo "int" y encontré que el tipo "int" se construye con el valor 0.
El valor predeterminado de los objetos de tipo clase es el establecido por el constructor predeterminado de la clase. Para los tipos incorporados, el valor predeterminado es 0.
Pero tenga en cuenta que existe una diferencia entre una variable incorporada que no está inicializada y una inicializada a su valor predeterminado. Una incorporada que no se inicialice probablemente retendrá cualquier valor que haya en la dirección de memoria de esa variable en ese momento.
int i; // i has an arbitrary undefined value
int x = int(); // x is 0
Esto se define en la norma, sí. El mapa está realizando "inicialización predeterminada" en este caso. Como usted dice, para los tipos de clase, eso llama a un constructor sin argumentos.
Para los tipos incorporados, en el estándar ''98, consulte la sección 8.5, "Inicializadores":
Para inicializar por defecto un objeto de tipo T significa:
- si T no es un POD ...
- si T es un tipo de matriz ...
- de lo contrario, el almacenamiento para el objeto es cero inicializado
Y, anteriormente,
Para cero inicializar el almacenamiento para un objeto de tipo T significa:
- Si T es un tipo escalar, el almacenamiento se establece en el valor 0 (cero) convertido a T
Los tipos escalares son:
- Tipos aritméticos (entero, coma flotante)
- Tipos de enumeración
- Tipos de puntero
- Puntero a tipos de miembros
En particular, el comportamiento que ve con un entero (inicializado a cero) está definido por el estándar, y puede confiar en él.
|expression: | POD type T | non-POD type T
==================================================================================================
| new T | not initialized | default-initialized
| new T() | always default-initialized | always default-initialized
| new T(x) | always initialized via a constructor | always initialized via a constructor
Por lo que sé, stl usa nueva T () para los valores predeterminados, por lo que se inicializará por defecto, en caso de int a 0.