"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > ¿Cuándo requiere la lista de inicialización del tipo de agregado C ++?

¿Cuándo requiere la lista de inicialización del tipo de agregado C ++?

Publicado el 2025-04-14
Navegar:317

When are Outer Braces Necessary in C   Initializer Lists for Aggregates?

sobre la omisión de los aparatos omitidos en las listas de inicializador para agregados y estructuras POD

en el reino de la programación C, una pregunta común surge con respecto al uso de las listas de los iniciales. Específicamente, los programadores pueden encontrar escenarios en los que parecen ser necesarios para ciertos tipos agregados pero no para otros. Este artículo tiene como objetivo profundizar en el tema y proporcionar una aclaración sobre cuándo se pueden omitir los aparatos ituter.

el problema [&]

al compilar el siguiente código en Visual C 2010, se genera un mensaje de error:

struct A Struct A { int foo; barra doble; }; std :: array a1 = // Error C2078: demasiados inicializadores { {0, 0.1}, {2, 3.4} }; // DE ACUERDO std :: array a2 = {0.1, 2.3};
struct A
{
    int foo;
    double bar;
};

std::array a1 = 
  // error C2078: too many initializers
  {
    {0, 0.1},
    {2, 3.4}
  };

// OK
std::array a2 = {0.1, 2.3};
El error indica que hay demasiados inicializadores para A1, lo que sugiere que se requieren los aparatos adicionales. Sin embargo, omitir los aparatos ortopédicos para A2 no da como resultado un error. Esta discrepancia plantea la pregunta de por qué se necesitan aparatos ortopédicos para A1 pero no para a2.

la explicación

la clave para comprender la razón detrás de esta diferencia se encuentra en la naturaleza de std :: array. std :: array se clasifica como un agregado y un tipo de datos (POD) simple, mientras que otros contenedores de biblioteca estándar no lo son. A diferencia de los contenedores con constructores definidos por el usuario, STD :: Array no tiene uno. Su primer miembro de datos es una matriz de tamaño N, especificada como un argumento de plantilla. Este miembro de datos se inicializa directamente utilizando una lista de inicializador. Los aparatos ortopédicos adicionales son necesarios porque encierran la matriz interna que se está inicializando.

para ilustrar este concepto aún más, considere un tipo de agregado personalizado aarray, definido como sigue:

// agregado personalizado sin ningún constructor definido por el usuario estructurar aarray { Un datos [2]; // una matriz interna };
struct A
{
    int foo;
    double bar;
};

std::array a1 = 
  // error C2078: too many initializers
  {
    {0, 0.1},
    {2, 3.4}
  };

// OK
std::array a2 = {0.1, 2.3};
La inicialización de esta estructura requiere el uso de aparatos ortopédicos para denotar el inicio y el final de la matriz interna que se inicializa:

aarray a1 = { {// comienza la inicialización de la matriz interna {// Inicializa el primer elemento de la matriz interna 0, 0.1 }, // finaliza la inicialización del primer elemento {2, 3.4} // Inicializa el segundo elemento de la matriz interna } // finaliza la inicialización de la matriz interna }; // Error: demasiados inicializadores si no usan aparatos ortopédicos Aarray b1 = { 0, 0.1, 2, 3.4 };
struct A
{
    int foo;
    double bar;
};

std::array a1 = 
  // error C2078: too many initializers
  {
    {0, 0.1},
    {2, 3.4}
  };

// OK
std::array a2 = {0.1, 2.3};

el caso de doble

en el caso de std :: array , la situación es diferente porque el doble no es un tipo de agregado. En cambio, std :: array se considera un agregado de primitivas. El siguiente código es válido sin aparatos ortopédicos exteriores porque los valores primitivos se inicializan directamente dentro del agregado:

std :: array a2 = {0.1, 2.3};
struct A
{
    int foo;
    double bar;
};

std::array a1 = 
  // error C2078: too many initializers
  {
    {0, 0.1},
    {2, 3.4}
  };

// OK
std::array a2 = {0.1, 2.3};

en el uso de los brazos

el estándar proporciona las guías de uso iniciales. La Sección §8.5.1/11 de la especificación C 11 establece que si la lista inicializador comienza con un aparato ortopédico izquierdo, entonces cada lista posterior de cláusulas iniciales separadas por comas inicializa a los miembros de un subagregado. Por otro lado, si la lista de inicializador para un subagregado no comienza con un aparato ortopédico izquierdo, entonces solo se tomarán suficientes cláusulas iniciales para inicializar los miembros subagregados, con cualquier cláusula inicializadora restante inicializando el siguiente miembro de agregado. Agregados y estructuras de POD, como STD :: Array, porque estos tipos no tienen constructores definidos por el usuario y la matriz interna se inicializa directamente. Para los tipos primitivos, por otro lado, los aparatos exteriores se pueden omitir ya que los valores primitivos se inicializan directamente dentro del agregado. Al comprender la diferencia entre estos casos, los programadores pueden garantizar la inicialización correcta y evitar errores del compilador.

Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3