argument - c++ initialize class with parameters
¿Por qué es diferente el comportamiento C++ initializer_list para std:: vector y std:: array? (2)
Código:
std::vector<int> x{1,2,3,4};
std::array<int, 4> y{{1,2,3,4}};
¿Por qué necesito llaves dobles para std :: array?
Porque std::vector
ofrece un constructor que toma std::initializer_list<T>
, mientras que std::array
no tiene constructores y {1, 2, 3, 4}
arriostrados init-list de hecho no se interpreta como std::initializer_list
, pero inicialización agregada para la matriz interna de estilo C de std::array
(de ahí viene el segundo conjunto de llaves: One para std::array
, uno para la matriz de miembros interna C-style).
std::array<T, N>
es un agregado: no tiene constructores declarados por el usuario, ni siquiera uno toma std::initializer_list
. La inicialización mediante llaves se realiza mediante la inicialización agregada , una característica de C ++ heredada de C.
El "viejo estilo" de inicialización agregada usa el =
std::array<int, 4> y = { { 1, 2, 3, 4 } };
Con este estilo antiguo de inicialización agregada, se pueden eliminar llaves adicionales, por lo que esto es equivalente a:
std::array<int, 4> y = { 1, 2, 3, 4 };
Sin embargo, estas llaves adicionales solo se pueden elidir "en una declaración de la forma T x = { a };
" (C ++ 11 §8.5.1 / 11), es decir, cuando se usa el estilo antiguo =
. Esta regla que permite la elisión del corsé no se aplica a la inicialización directa de la lista. Una nota a pie de página aquí dice: "Las llaves no se pueden elidir en otros usos de inicialización de listas".
Hay un informe de defectos con respecto a esta restricción: defecto CWG # 1270 . Si se adopta la resolución propuesta, se permitirá la elisión del paréntesis para otras formas de inicialización de la lista, y lo siguiente estará bien formado:
std::array<int, 4> y{ 1, 2, 3, 4 };
(Sombrero de punta a Ville Voutilainen para encontrar el informe de defectos).