Con C ++ 11 std::array
, ¿tengo la garantía de que la sintaxis std::array<T, N> x;
inicializará por defecto todos los elementos de la matriz?
EDITAR : si no, ¿existe una sintaxis que funcione en todas las matrices (incluidas las matrices de tamaño cero) para inicializar todos los elementos a su valor predeterminado?
EDITAR : en cppreference , la descripción del constructor predeterminado dice:
(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array
entonces la respuesta puede ser sí. Pero me gustaría estar seguro de eso de acuerdo con el estándar o estándar futuro.
T x[N]
sintaxis.Respuestas:
Por definición, la inicialización predeterminada es la inicialización que se produce cuando no se especifica ninguna otra inicialización; el lenguaje C ++ le garantiza que cualquier objeto para el que no proporcione un inicializador explícito se inicializará por defecto (C ++ 11 §8.5 / 11). Eso incluye objetos de tipo
std::array<T, N>
yT[N]
.Tenga en cuenta que hay tipos para los que la inicialización predeterminada no tiene ningún efecto y deja indeterminado el valor del objeto: cualquier tipo que no sea de clase ni de matriz (§8.5 / 6). En consecuencia, una matriz de objetos inicializada por defecto con tales tipos tendrá un valor indeterminado, por ejemplo:
Tanto la matriz de estilo c como
std::array
se rellenan con números enteros de valor indeterminado, al igual queplain_int
tiene valor indeterminado.Supongo que cuando dice "a su valor predeterminado" realmente quiere decir "inicializar todos los elementos a
T{}
". Eso no es inicialización predeterminada , es inicialización de valor (8.5 / 7). Puede solicitar la inicialización de valor con bastante facilidad en C ++ 11 dando a cada declaración un inicializador vacío:Lo que inicializará con valor todos los elementos de la matriz a su vez, lo que dará como resultado
plain_old_int
, y todos los miembros de ambos tipos de matrices, que se inicialicen a cero.fuente
boost::value_initialized
enlace, pero creo que VC12 (VS2013) tiene un soporte mucho mejor ahora.La inicialización predeterminada es un término del Estándar que potencialmente significa que no hay inicialización en absoluto, por lo que probablemente se refiera a la inicialización cero .
La descripción en cppreference.com es en realidad un poco engañosa.
std::array
es una clase agregada, y si el tipo de elemento es primitivo, es POD: "datos antiguos sin formato", con semántica que coincide estrechamente con el lenguaje C. El constructor implícitamente definido destd::array< int, N >
es uno trivial que no hace absolutamente nada.La sintaxis similar
std::array< int, 3 >()
ostd::array< int, 3 > x{}
que proporciona valores cero no lo hace invocando un constructor. Obtener ceros es parte de la inicialización de valor , especificado en C ++ 11 §8.5 / 8:std::array
no tiene un constructor predeterminado proporcionado por el usuario, por lo que se inicializa en cero. Tiene un constructor predeterminado definido implícitamente, pero es trivial, por lo que nunca se inicializa por defecto. (Pero esto no hace una diferencia ya que la inicialización trivial por definición no tiene ningún efecto en el tiempo de ejecución).Los arreglos de estilo C y
std::array
ambos son agregados, y la forma de inicializar completamente a cero cualquier agregado es con la sintaxis= {}
. Esto funciona desde C ++ 98. Tenga en cuenta que las matrices de estilo C no pueden tener una extensión cero y quesizeof (std::array< X, 0 >)
no es cero.fuente
Ambos
T x[N];
y porstd::array<T, N> x;
defecto inicializan cada elemento de la matriz.Por ejemplo, si
T = std::string
, cada elemento será una cadena vacía. SiT
es una clase sin un constructor predeterminado, ambos fallarán al compilar. SiT = int
, cada elemento tendrá un valor indeterminado (a menos que esa declaración esté en el ámbito del espacio de nombres)fuente
En primer lugar, T x [N] inicializa los elementos por defecto, aunque la inicialización por defecto de un tipo escalar T en realidad no hace nada. Lo anterior también es válido para std :: array x. Creo que lo que necesita es la inicialización de la lista.
fuente