voto ventajas son qué por para listas lista las ejemplo desventajas congreso colombia cerradas cerrada abiertas abierta c++ initialization initializer-list initializer curly-braces

c++ - son - ventajas y desventajas de las listas abiertas



¿Qué es una lista cerrada de corsé si no es una lista inicial? (4)

Hice una pregunta aquí: Lifetime Extension de una declaración initializer_list que implica el código no funcional:

const auto foo = [](const auto& a, const auto& b, const auto& c) { return {a, b, c}; };

intializer_list que la lambda intentaba devolver una lista intializer_list (eso es malo, no hagas eso). Pero tengo un comment :

No es una initializer_list , es una lista de inicializadores. Dos cosas diferentes

Solo pensé que cada vez que hacía una lista de intializer_list estaba creando una intializer_list . Si eso no es lo que está pasando, ¿qué es una lista de llaves?


Solo pensé que cada vez que hacía una lista de intializer_list estaba creando una intializer_list .

Eso no es correcto

Si eso no es lo que está pasando, ¿qué es una lista de llaves?

struct Foo {int a; int b;}; Foo f = {10, 20};

La parte {10, 20} no es una initializer_list . Es solo una forma sintáctica para usar una lista de objetos para crear otro objeto.

int a[] = {10, 20, 30};

Una vez más, es una forma sintáctica para crear una matriz.

El nombre para la forma sintáctica es braced-init-list .


Aquí hay tres conceptos distintos, pero relacionados:

  1. braced-init-list : la regla gramatical asociada con las listas de llaves incluidas en ciertos contextos.

  2. Lista de inicializador: el nombre para el inicializador de lista de inicialización de braced utilizado en la inicialización de lista .

  3. std::initializer_list : una clase que envuelve una matriz temporal que se crea en algunos contextos que incluyen braced-init-list s.

Algunos ejemplos:

//a braced-init-list and initializer list, //but doesn''t create a std::initializer_list int a {4}; //a braced-init-list and initializer list, //creates a std::initializer_list std::vector b {1, 2, 3}; //a braced-init-list and initializer list, //does not create a std::initializer_list (aggregate initialization) int c[] = {1, 2, 3}; //d is a std::initializer_list created from an initializer list std::initializer_list d {1, 2, 3}; //e is std::initializer_list<int> auto e = { 4 }; //f used to be a std::initializer_list<int>, but is now int after N3922 auto f { 4 };

Es posible que desee leer N3922 , que cambió algunas de las reglas que implican auto y std::initializer_list .


Es una lista inicial arrinconada . Una lista de std::initializer_list existía antes de std::initializer_list y se usa para inicializar agregados .

int arr[] = {1,2,3,4,5};

Lo anterior usó una lista de inicio reforzada para inicializar la matriz, no se creó std::initializer_list . Por otro lado, cuando lo haces

std::vector<int> foo = {1,2,3,4,5};

foo no es un agregado, por lo que la lista de inicio de llaves forzadas se usa para crear una lista std::initializer_list que luego se pasa al constructor de foo que acepta una lista std::initializer_list .

Una cosa a tener en cuenta acerca de una lista de inicio reforzada es que no tiene ningún tipo, por lo que se desarrollaron reglas especiales para usar con ella y auto . Tiene el siguiente comportamiento (desde la adopción de N3922 )

auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int> auto x5{ 3 }; // decltype(x5) is int

Y puede obtener más información sobre el historial de este comportamiento y por qué se modificó en: ¿Por qué auto x {3} deduce una initializer_list?


Tienes dos cosas diferentes cuando usas {}

  1. A Tipo std::initializer_list<T> donde los valores se pueden convertir implícitamente a T
  2. Un tipo que se puede inicializar con los valores de la lista.

El primer tipo fuerza una lista homogénea y el segundo tipo no. En el siguiente ejemplo:

struct S{ int a; string b }; void f1( S s ); void f2( int i ); void f3( std::initializer_list<int> l ); f1( {1, "zhen"} ); // construct a temporal S f2( {1} ); // construct a temporal int f3( {1,2,3} ); // construct a temporal list of ints

Las funciones f1 y f2 usan el primer tipo y f3 usan el segundo tipo. Debe saber que si hay ambigüedad, se prefiere std :: initializer_list. P.ej:

void f( S s ); void f( int i ); void f( std::initializer_list<int> l ); f( {1, "zhen"} ); // calls with struct S f( {1} ); // calls with int list with one element f( {1,2,3} ); // calls with int list with three elements