Inicializando una matriz miembro en el inicializador del constructor

class C { public: C() : arr({1,2,3}) //doesn't compile {} /* C() : arr{1,2,3} //doesn't compile either {} */ private: int arr[3]; }; 

Creo que la razón es que las matrices solo se pueden inicializar con la syntax = , es decir:

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

Preguntas

  1. ¿Cómo puedo hacer lo que quiero hacer (es decir, inicializar una matriz en un constructor (no asignar elementos en el cuerpo)). ¿Es posible?
  2. ¿El estándar C ++ 03 dice algo especial sobre la inicialización de agregados (incluidas las matrices) en los inicializadores de Ctor? ¿O la invalidez del código anterior es un corolario de algunas otras reglas?
  3. ¿Las listas de inicializadores de C ++ 0x resuelven el problema?

PD Por favor, no mencione vectores, boost :: arrays, y su superioridad a las matrices, de las que soy consciente.

  1. ¿Cómo puedo hacer lo que quiero hacer (es decir, inicializar una matriz en un constructor (no asignar elementos en el cuerpo)). ¿Es posible?

Sí. Está usando una estructura que contiene una matriz. Usted dice que ya sabe sobre eso, pero luego no entiendo la pregunta. De esta forma, inicializa una matriz en el constructor, sin asignaciones en el cuerpo. Esto es lo que boost::array hace.

¿El estándar C ++ 03 dice algo especial sobre la inicialización de agregados (incluidas las matrices) en los inicializadores de Ctor? ¿O la invalidez del código anterior es un corolario de algunas otras reglas?

Un mem-initializer usa inicialización directa. Y las reglas de la cláusula 8 prohíben este tipo de cosas. No estoy exactamente seguro sobre el siguiente caso, pero algunos comstackdores lo permiten.

 struct A { char foo[6]; A():foo("hello") { } /* valid? */ }; 

Ver este GCC PR para más detalles.

¿Las listas de inicializadores de C ++ 0x resuelven el problema?

Ellos si. Sin embargo, su syntax es inválida, creo. Tienes que usar llaves directamente para disparar la inicialización de la lista

 struct A { int foo[3]; A():foo{1, 2, 3} { } A():foo({1, 2, 3}) { } /* invalid */ }; 

C ++ 98 no proporciona una syntax directa para nada excepto la puesta a cero (o para elementos que no sean POD, inicialización del valor) de la matriz. Para eso, simplemente escribe C(): arr() {} .

Creo que Roger Pate está equivocado sobre las supuestas limitaciones de la inicialización agregada C ++ 0x, pero soy demasiado flojo para buscarlo o comprobarlo, y no importa, ¿verdad? EDITAR : Roger estaba hablando de “C ++ 03”, lo interpreté mal como “C ++ 0x”. Lo siento, Roger. ☺

Una solución C ++ 98 para su código actual es envolver la matriz en una struct e inicializarla a partir de una constante estática de ese tipo. Los datos tienen que residir en algún lugar de todos modos. Fuera del manguito puede verse así:

 class C { public: C() : arr( arrData ) {} private: struct Arr{ int elem[3]; }; Arr arr; static Arr const arrData; }; C::Arr const C::arrData = {{1, 2, 3}}; 

Solución:

 template struct simple_array { // like std::array in C++0x T arr[N]; }; class C : private simple_array { static simple_array myarr() { simple_array arr = {1,2,3}; return arr; } public: C() : simple_array(myarr()) {} }; 
  1. No Desafortunadamente.
  2. Simplemente no puedes en la forma que quieres, ya que no está permitido por la gramática (más abajo). Solo puede usar la inicialización tipo ctor y, como usted sabe, eso no está disponible para inicializar cada elemento en las matrices.
  3. Creo que sí, ya que generalizan la inicialización en general de muchas maneras útiles. Pero no estoy seguro de los detalles.

En C ++ 03, la inicialización agregada solo se aplica con una syntax similar a la siguiente, que debe ser una instrucción separada y no cabe en un inicializador de ctor.

 T var = {...}; 

Qué tal si

 ... C() : arr{ {1,2,3} } {} ... 

?

Comstack bien en g ++ 4.8

¿Desea iniciar una matriz de ints en su constructor? Apúntalo a una matriz estática.

 class C { public: int *cArray; }; C::C { static int c_init[]{1,2,3}; cArray = c_init; }