with initialize argument c++ stl c++11

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).